diff options
author | gman@chromium.org <gman@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2011-06-27 22:34:47 +0000 |
---|---|---|
committer | gman@chromium.org <gman@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2011-06-27 22:34:47 +0000 |
commit | 40c7ee4e84ba84f73b85521b47fe33e866c1d2da (patch) | |
tree | d2589e6da164405649f2818a0e45c083488a5b23 /gpu | |
parent | c66019913aa4948835a24ca0f9feccb63003a6d7 (diff) | |
download | chromium_src-40c7ee4e84ba84f73b85521b47fe33e866c1d2da.zip chromium_src-40c7ee4e84ba84f73b85521b47fe33e866c1d2da.tar.gz chromium_src-40c7ee4e84ba84f73b85521b47fe33e866c1d2da.tar.bz2 |
Add glGetMultipleIntegervCHROMIUM
This is a step to adding more client side state caching.
TEST=unit tests
BUG=85969
R=apatrick@chromium.org
Review URL: http://codereview.chromium.org/7217029
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@90662 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'gpu')
20 files changed, 553 insertions, 14 deletions
diff --git a/gpu/GLES2/gl2ext.h b/gpu/GLES2/gl2ext.h index 8738f82..2c092e6 100644 --- a/gpu/GLES2/gl2ext.h +++ b/gpu/GLES2/gl2ext.h @@ -990,6 +990,23 @@ typedef void (GL_APIENTRYP PFNGLRATELIMITOFFSCREENCONTEXTCHROMIUM) (); #endif #endif +/* GL_CHROMIUM_get_multiple */ +/* + * This extension provides functions for quering multiple GL state with a single + * call. + */ +#ifndef GL_CHROMIUM_get_multiple +#define GL_CHROMIUM_get_multiple 1 +#ifdef GL_GLEXT_PROTOTYPES +#define glGetMultipleIntegervCHROMIUM GLES2_GET_FUN(GetMultipleIntegervCHROMIUM) +#if !defined(GLES2_USE_CPP_BINDINGS) +GL_APICALL void GL_APIENTRY glGetMultipleIntegervCHROMIUM (void); +#endif +#else +typedef void (GL_APIENTRYP PFNGLGETMULTIPLEINTEGERVCHROMIUM) (); +#endif +#endif + #ifdef __cplusplus } #endif diff --git a/gpu/command_buffer/build_gles2_cmd_buffer.py b/gpu/command_buffer/build_gles2_cmd_buffer.py index 99cf0d3..9527415 100755 --- a/gpu/command_buffer/build_gles2_cmd_buffer.py +++ b/gpu/command_buffer/build_gles2_cmd_buffer.py @@ -221,6 +221,7 @@ GL_APICALL void GL_APIENTRY glSetLatchCHROMIUM (GLuint latch_id); GL_APICALL void GL_APIENTRY glWaitLatchCHROMIUM (GLuint latch_id); GL_APICALL void GL_APIENTRY glRateLimitOffscreenContextCHROMIUM (void); GL_APICALL void GL_APIENTRY glSetSurfaceCHROMIUM (GLint surface_id); +GL_APICALL void GL_APIENTRY glGetMultipleIntegervCHROMIUM (const GLenum* pnames, GLuint count, GLint* results, GLsizeiptr size); """ # This is the list of all commmands that will be generated and their Id. @@ -427,6 +428,7 @@ _CMD_ID_TABLE = { 'SetLatchCHROMIUM': 451, 'WaitLatchCHROMIUM': 452, 'SetSurfaceCHROMIUM': 453, + 'GetMultipleIntegervCHROMIUM': 454, } # This is a list of enum names and their valid values. It is used to map @@ -1327,6 +1329,13 @@ _FUNCTION_INFO = { 'extension': True, 'chromium': True, }, + 'GetMultipleIntegervCHROMIUM': { + 'type': 'Custom', + 'immediate': False, + 'expectation': False, + 'extension': True, + 'chromium': True, + }, 'GetProgramiv': { 'type': 'GETn', 'decoder_func': 'DoGetProgramiv', diff --git a/gpu/command_buffer/client/gles2_c_lib_autogen.h b/gpu/command_buffer/client/gles2_c_lib_autogen.h index 091d565..72a39db 100644 --- a/gpu/command_buffer/client/gles2_c_lib_autogen.h +++ b/gpu/command_buffer/client/gles2_c_lib_autogen.h @@ -2,7 +2,9 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -// This file is auto-generated. DO NOT EDIT! +// This file is auto-generated from +// gpu/command_buffer/build_gles2_cmd_buffer.py +// DO NOT EDIT! // These functions emluate GLES2 over command buffers. #ifndef GPU_COMMAND_BUFFER_CLIENT_GLES2_C_LIB_AUTOGEN_H_ @@ -578,6 +580,11 @@ void GLES2RateLimitOffscreenContextCHROMIUM() { void GLES2SetSurfaceCHROMIUM(GLint surface_id) { gles2::GetGLContext()->SetSurfaceCHROMIUM(surface_id); } +void GLES2GetMultipleIntegervCHROMIUM( + const GLenum* pnames, GLuint count, GLint* results, GLsizeiptr size) { + gles2::GetGLContext()->GetMultipleIntegervCHROMIUM( + pnames, count, results, size); +} #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 c8deb23..2cc91eb 100644 --- a/gpu/command_buffer/client/gles2_cmd_helper_autogen.h +++ b/gpu/command_buffer/client/gles2_cmd_helper_autogen.h @@ -2,7 +2,9 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -// This file is auto-generated. DO NOT EDIT! +// This file is auto-generated from +// gpu/command_buffer/build_gles2_cmd_buffer.py +// DO NOT EDIT! #ifndef GPU_COMMAND_BUFFER_CLIENT_GLES2_CMD_HELPER_AUTOGEN_H_ #define GPU_COMMAND_BUFFER_CLIENT_GLES2_CMD_HELPER_AUTOGEN_H_ @@ -1232,5 +1234,15 @@ c.Init(surface_id); } + void GetMultipleIntegervCHROMIUM( + uint32 pnames_shm_id, uint32 pnames_shm_offset, GLuint count, + uint32 results_shm_id, uint32 results_shm_offset, GLsizeiptr size) { + gles2::GetMultipleIntegervCHROMIUM& c = + GetCmdSpace<gles2::GetMultipleIntegervCHROMIUM>(); + c.Init( + pnames_shm_id, pnames_shm_offset, count, results_shm_id, + results_shm_offset, size); + } + #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 a8f16f9..6a215a4 100644 --- a/gpu/command_buffer/client/gles2_implementation.cc +++ b/gpu/command_buffer/client/gles2_implementation.cc @@ -2006,5 +2006,60 @@ void GLES2Implementation::RateLimitOffscreenContextCHROMIUM() { rate_limit_tokens_.push(helper_->InsertToken()); } +void GLES2Implementation::GetMultipleIntegervCHROMIUM( + const GLenum* pnames, GLuint count, GLint* results, GLsizeiptr size) { + GPU_CLIENT_LOG("[" << this << "] glGetMultipleIntegervCHROMIUM(" + << static_cast<const void*>(pnames) << ", " + << count << ", " << results << ", " << size << ")"); + GPU_CLIENT_LOG_CODE_BLOCK({ + for (GLuint i = 0; i < count; ++i) { + GPU_CLIENT_LOG( + " " << i << ": " << GLES2Util::GetStringGLState(pnames[i])); + } + }); + int num_results = 0; + for (GLuint ii = 0; ii < count; ++ii) { + int num = util_.GLGetNumValuesReturned(pnames[ii]); + if (!num) { + SetGLError(GL_INVALID_ENUM, "glGetMultipleIntegervCHROMIUM: bad pname"); + return; + } + num_results += num; + } + if (static_cast<size_t>(size) != num_results * sizeof(GLint)) { + SetGLError(GL_INVALID_VALUE, "glGetMultipleIntegervCHROMIUM: bad size"); + return; + } + for (int ii = 0; ii < num_results; ++ii) { + if (results[ii] != 0) { + SetGLError(GL_INVALID_VALUE, + "glGetMultipleIntegervCHROMIUM: results not set to zero."); + return; + } + } + uint32 size_needed = + count * sizeof(pnames[0]) + num_results * sizeof(results[0]); + void* buffer = transfer_buffer_.Alloc(size_needed); + GLenum* pnames_buffer = static_cast<GLenum*>(buffer); + void* results_buffer = pnames_buffer + count; + memcpy(pnames_buffer, pnames, count * sizeof(GLenum)); + memset(results_buffer, 0, num_results * sizeof(GLint)); + helper_->GetMultipleIntegervCHROMIUM( + transfer_buffer_id_, transfer_buffer_.GetOffset(pnames_buffer), + count, + transfer_buffer_id_, transfer_buffer_.GetOffset(results_buffer), + size); + WaitForCmd(); + memcpy(results, results_buffer, size); + // TODO(gman): We should be able to free without a token. + transfer_buffer_.FreePendingToken(buffer, helper_->InsertToken()); + GPU_CLIENT_LOG(" returned"); + GPU_CLIENT_LOG_CODE_BLOCK({ + for (int i = 0; i < num_results; ++i) { + GPU_CLIENT_LOG(" " << i << ": " << (results[i])); + } + }); +} + } // namespace gles2 } // namespace gpu diff --git a/gpu/command_buffer/client/gles2_implementation_autogen.h b/gpu/command_buffer/client/gles2_implementation_autogen.h index eb148a2..55e8248 100644 --- a/gpu/command_buffer/client/gles2_implementation_autogen.h +++ b/gpu/command_buffer/client/gles2_implementation_autogen.h @@ -2,7 +2,9 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -// This file is auto-generated. DO NOT EDIT! +// This file is auto-generated from +// gpu/command_buffer/build_gles2_cmd_buffer.py +// DO NOT EDIT! // This file is included by gles2_implementation.h to declare the // GL api functions. @@ -1227,5 +1229,8 @@ void SetSurfaceCHROMIUM(GLint surface_id) { helper_->SetSurfaceCHROMIUM(surface_id); } +void GetMultipleIntegervCHROMIUM( + const GLenum* pnames, GLuint count, GLint* results, GLsizeiptr size); + #endif // GPU_COMMAND_BUFFER_CLIENT_GLES2_IMPLEMENTATION_AUTOGEN_H_ diff --git a/gpu/command_buffer/client/gles2_implementation_unittest.cc b/gpu/command_buffer/client/gles2_implementation_unittest.cc index 68f2e6b..0b81479 100644 --- a/gpu/command_buffer/client/gles2_implementation_unittest.cc +++ b/gpu/command_buffer/client/gles2_implementation_unittest.cc @@ -137,6 +137,10 @@ ACTION_P2(SetMemoryAtOffset, offset, obj) { memcpy(static_cast<char*>(arg0) + offset, &obj, sizeof(obj)); } +ACTION_P3(SetMemoryAtOffsetFromArray, offset, array, size) { + memcpy(static_cast<char*>(arg0) + offset, array, size); +} + // Used to help set the transfer buffer result to SizedResult of a single value. template <typename T> class SizedResultHelper { @@ -215,11 +219,22 @@ class GLES2ImplementationTest : public testing::Test { Buffer ring_buffer = command_buffer_->GetRingBuffer(); commands_ = static_cast<CommandBufferEntry*>(ring_buffer.ptr) + command_buffer_->GetState().put_offset; + ClearCommands(); } virtual void TearDown() { } + void ClearCommands() { + Buffer ring_buffer = command_buffer_->GetRingBuffer(); + memset(ring_buffer.ptr, kInitialValue, ring_buffer.size); + } + + bool NoCommandsWritten() { + return static_cast<const uint8*>(static_cast<const void*>(commands_))[0] == + kInitialValue; + } + void ClearTransferBuffer() { memset(transfer_buffer_.ptr, kInitialValue, kTransferBufferSize); } @@ -976,6 +991,108 @@ TEST_F(GLES2ImplementationTest, MapUnmapTexSubImage2DCHROMIUMBadArgs) { EXPECT_EQ(static_cast<GLenum>(GL_INVALID_VALUE), gl_->GetError()); } +TEST_F(GLES2ImplementationTest, GetMultipleIntegervCHROMIUMValidArgs) { + const GLenum pnames[] = { + GL_DEPTH_WRITEMASK, + GL_COLOR_WRITEMASK, + GL_STENCIL_WRITEMASK, + }; + const GLint num_results = 6; + GLint results[num_results + 1]; + struct Cmds { + GetMultipleIntegervCHROMIUM get_multiple; + cmd::SetToken set_token; + }; + const GLsizei kNumPnames = arraysize(pnames); + const GLsizeiptr kResultsSize = num_results * sizeof(results[0]); + const uint32 kPnamesOffset = GLES2Implementation::kStartingOffset; + const uint32 kResultsOffset = kPnamesOffset + kNumPnames * sizeof(pnames[0]); + int32 token = 1; + Cmds expected; + expected.get_multiple.Init( + kTransferBufferId, kPnamesOffset, kNumPnames, + kTransferBufferId, kResultsOffset, kResultsSize); + expected.set_token.Init(token++); + + const GLint kSentinel = 0x12345678; + memset(results, 0, sizeof(results)); + results[num_results] = kSentinel; + const GLint returned_results[] = { + 1, 0, 1, 0, 1, -1, + }; + // One call to flush to wait for results + EXPECT_CALL(*command_buffer_, OnFlush(_)) + .WillOnce(SetMemoryAtOffsetFromArray( + kResultsOffset, returned_results, sizeof(returned_results))) + .WillOnce(SetMemory(GLuint(GL_NO_ERROR))) + .RetiresOnSaturation(); + + gl_->GetMultipleIntegervCHROMIUM( + &pnames[0], kNumPnames, &results[0], kResultsSize); + EXPECT_EQ(0, memcmp(&expected, commands_, sizeof(expected))); + EXPECT_EQ(0, memcmp(&returned_results, results, sizeof(returned_results))); + EXPECT_EQ(kSentinel, results[num_results]); + EXPECT_EQ(static_cast<GLenum>(GL_NO_ERROR), gl_->GetError()); +} + +TEST_F(GLES2ImplementationTest, GetMultipleIntegervCHROMIUMBadArgs) { + GLenum pnames[] = { + GL_DEPTH_WRITEMASK, + GL_COLOR_WRITEMASK, + GL_STENCIL_WRITEMASK, + }; + const GLint num_results = 6; + GLint results[num_results + 1]; + const GLsizei kNumPnames = arraysize(pnames); + const GLsizeiptr kResultsSize = num_results * sizeof(results[0]); + + // Calls to flush to wait for GetError + EXPECT_CALL(*command_buffer_, OnFlush(_)) + .WillOnce(SetMemory(GLuint(GL_NO_ERROR))) + .WillOnce(SetMemory(GLuint(GL_NO_ERROR))) + .WillOnce(SetMemory(GLuint(GL_NO_ERROR))) + .WillOnce(SetMemory(GLuint(GL_NO_ERROR))) + .RetiresOnSaturation(); + + const GLint kSentinel = 0x12345678; + memset(results, 0, sizeof(results)); + results[num_results] = kSentinel; + // try bad size. + gl_->GetMultipleIntegervCHROMIUM( + &pnames[0], kNumPnames, &results[0], kResultsSize + 1); + EXPECT_TRUE(NoCommandsWritten()); + EXPECT_EQ(static_cast<GLenum>(GL_INVALID_VALUE), gl_->GetError()); + EXPECT_EQ(0, results[0]); + EXPECT_EQ(kSentinel, results[num_results]); + // try bad size. + ClearCommands(); + gl_->GetMultipleIntegervCHROMIUM( + &pnames[0], kNumPnames, &results[0], kResultsSize - 1); + EXPECT_TRUE(NoCommandsWritten()); + EXPECT_EQ(static_cast<GLenum>(GL_INVALID_VALUE), gl_->GetError()); + EXPECT_EQ(0, results[0]); + EXPECT_EQ(kSentinel, results[num_results]); + // try uncleared results. + ClearCommands(); + results[2] = 1; + gl_->GetMultipleIntegervCHROMIUM( + &pnames[0], kNumPnames, &results[0], kResultsSize); + EXPECT_TRUE(NoCommandsWritten()); + EXPECT_EQ(static_cast<GLenum>(GL_INVALID_VALUE), gl_->GetError()); + EXPECT_EQ(0, results[0]); + EXPECT_EQ(kSentinel, results[num_results]); + // try bad enum results. + ClearCommands(); + results[2] = 0; + pnames[1] = GL_TRUE; + gl_->GetMultipleIntegervCHROMIUM( + &pnames[0], kNumPnames, &results[0], kResultsSize); + EXPECT_TRUE(NoCommandsWritten()); + EXPECT_EQ(static_cast<GLenum>(GL_INVALID_ENUM), gl_->GetError()); + EXPECT_EQ(0, results[0]); + EXPECT_EQ(kSentinel, results[num_results]); +} + } // namespace gles2 } // namespace gpu diff --git a/gpu/command_buffer/common/gles2_cmd_format_autogen.h b/gpu/command_buffer/common/gles2_cmd_format_autogen.h index 67bbc36..6270f9a 100644 --- a/gpu/command_buffer/common/gles2_cmd_format_autogen.h +++ b/gpu/command_buffer/common/gles2_cmd_format_autogen.h @@ -2,7 +2,9 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -// This file is auto-generated. DO NOT EDIT! +// This file is auto-generated from +// gpu/command_buffer/build_gles2_cmd_buffer.py +// DO NOT EDIT! #ifndef GPU_COMMAND_BUFFER_COMMON_GLES2_CMD_FORMAT_AUTOGEN_H_ #define GPU_COMMAND_BUFFER_COMMON_GLES2_CMD_FORMAT_AUTOGEN_H_ @@ -9013,6 +9015,68 @@ COMPILE_ASSERT(offsetof(SetSurfaceCHROMIUM, header) == 0, COMPILE_ASSERT(offsetof(SetSurfaceCHROMIUM, surface_id) == 4, OffsetOf_SetSurfaceCHROMIUM_surface_id_not_4); +struct GetMultipleIntegervCHROMIUM { + typedef GetMultipleIntegervCHROMIUM ValueType; + static const CommandId kCmdId = kGetMultipleIntegervCHROMIUM; + static const cmd::ArgFlags kArgFlags = cmd::kFixed; + + static uint32 ComputeSize() { + return static_cast<uint32>(sizeof(ValueType)); // NOLINT + } + + void SetHeader() { + header.SetCmd<ValueType>(); + } + + void Init( + uint32 _pnames_shm_id, uint32 _pnames_shm_offset, GLuint _count, + uint32 _results_shm_id, uint32 _results_shm_offset, GLsizeiptr _size) { + SetHeader(); + pnames_shm_id = _pnames_shm_id; + pnames_shm_offset = _pnames_shm_offset; + count = _count; + results_shm_id = _results_shm_id; + results_shm_offset = _results_shm_offset; + size = _size; + } + + void* Set( + void* cmd, uint32 _pnames_shm_id, uint32 _pnames_shm_offset, + GLuint _count, uint32 _results_shm_id, uint32 _results_shm_offset, + GLsizeiptr _size) { + static_cast<ValueType*>( + cmd)->Init( + _pnames_shm_id, _pnames_shm_offset, _count, _results_shm_id, + _results_shm_offset, _size); + return NextCmdAddress<ValueType>(cmd); + } + + gpu::CommandHeader header; + uint32 pnames_shm_id; + uint32 pnames_shm_offset; + uint32 count; + uint32 results_shm_id; + uint32 results_shm_offset; + int32 size; +}; + +COMPILE_ASSERT(sizeof(GetMultipleIntegervCHROMIUM) == 28, + Sizeof_GetMultipleIntegervCHROMIUM_is_not_28); +COMPILE_ASSERT(offsetof(GetMultipleIntegervCHROMIUM, header) == 0, + OffsetOf_GetMultipleIntegervCHROMIUM_header_not_0); +COMPILE_ASSERT(offsetof(GetMultipleIntegervCHROMIUM, pnames_shm_id) == 4, + OffsetOf_GetMultipleIntegervCHROMIUM_pnames_shm_id_not_4); +COMPILE_ASSERT(offsetof(GetMultipleIntegervCHROMIUM, pnames_shm_offset) == 8, + OffsetOf_GetMultipleIntegervCHROMIUM_pnames_shm_offset_not_8); +COMPILE_ASSERT(offsetof(GetMultipleIntegervCHROMIUM, count) == 12, + OffsetOf_GetMultipleIntegervCHROMIUM_count_not_12); +COMPILE_ASSERT(offsetof(GetMultipleIntegervCHROMIUM, results_shm_id) == 16, + OffsetOf_GetMultipleIntegervCHROMIUM_results_shm_id_not_16); +COMPILE_ASSERT(offsetof(GetMultipleIntegervCHROMIUM, results_shm_offset) == 20, + OffsetOf_GetMultipleIntegervCHROMIUM_results_shm_offset_not_20); +COMPILE_ASSERT(offsetof(GetMultipleIntegervCHROMIUM, size) == 24, + OffsetOf_GetMultipleIntegervCHROMIUM_size_not_24); + #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 0f18f94..212f8b3 100644 --- a/gpu/command_buffer/common/gles2_cmd_format_test_autogen.h +++ b/gpu/command_buffer/common/gles2_cmd_format_test_autogen.h @@ -2,7 +2,9 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -// This file is auto-generated. DO NOT EDIT! +// This file is auto-generated from +// gpu/command_buffer/build_gles2_cmd_buffer.py +// DO NOT EDIT! // This file contains unit tests for gles2 commmands // It is included by gles2_cmd_format_test.cc @@ -3547,5 +3549,28 @@ TEST(GLES2FormatTest, SetSurfaceCHROMIUM) { EXPECT_EQ(static_cast<GLint>(11), cmd.surface_id); } +TEST(GLES2FormatTest, GetMultipleIntegervCHROMIUM) { + GetMultipleIntegervCHROMIUM cmd = { { 0 } }; + void* next_cmd = cmd.Set( + &cmd, + static_cast<uint32>(11), + static_cast<uint32>(12), + static_cast<GLuint>(13), + static_cast<uint32>(14), + static_cast<uint32>(15), + static_cast<GLsizeiptr>(16)); + EXPECT_EQ(static_cast<uint32>(GetMultipleIntegervCHROMIUM::kCmdId), + cmd.header.command); + EXPECT_EQ(sizeof(cmd), cmd.header.size * 4u); + EXPECT_EQ(static_cast<char*>(next_cmd), + reinterpret_cast<char*>(&cmd) + sizeof(cmd)); + EXPECT_EQ(static_cast<uint32>(11), cmd.pnames_shm_id); + EXPECT_EQ(static_cast<uint32>(12), cmd.pnames_shm_offset); + EXPECT_EQ(static_cast<GLuint>(13), cmd.count); + EXPECT_EQ(static_cast<uint32>(14), cmd.results_shm_id); + EXPECT_EQ(static_cast<uint32>(15), cmd.results_shm_offset); + EXPECT_EQ(static_cast<GLsizeiptr>(16), cmd.size); +} + #endif // GPU_COMMAND_BUFFER_COMMON_GLES2_CMD_FORMAT_TEST_AUTOGEN_H_ diff --git a/gpu/command_buffer/common/gles2_cmd_ids_autogen.h b/gpu/command_buffer/common/gles2_cmd_ids_autogen.h index 5a3dc2d..95698a6 100644 --- a/gpu/command_buffer/common/gles2_cmd_ids_autogen.h +++ b/gpu/command_buffer/common/gles2_cmd_ids_autogen.h @@ -2,7 +2,9 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -// This file is auto-generated. DO NOT EDIT! +// This file is auto-generated from +// gpu/command_buffer/build_gles2_cmd_buffer.py +// DO NOT EDIT! #ifndef GPU_COMMAND_BUFFER_COMMON_GLES2_CMD_IDS_AUTOGEN_H_ #define GPU_COMMAND_BUFFER_COMMON_GLES2_CMD_IDS_AUTOGEN_H_ @@ -206,6 +208,7 @@ OP(SetLatchCHROMIUM) /* 451 */ \ OP(WaitLatchCHROMIUM) /* 452 */ \ OP(SetSurfaceCHROMIUM) /* 453 */ \ + OP(GetMultipleIntegervCHROMIUM) /* 454 */ \ enum CommandId { kStartPoint = cmd::kLastCommonId, // All GLES2 commands start after this. diff --git a/gpu/command_buffer/common/gles2_cmd_utils_autogen.h b/gpu/command_buffer/common/gles2_cmd_utils_autogen.h index 65da046..c562c4e 100644 --- a/gpu/command_buffer/common/gles2_cmd_utils_autogen.h +++ b/gpu/command_buffer/common/gles2_cmd_utils_autogen.h @@ -2,7 +2,9 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -// This file is auto-generated. DO NOT EDIT! +// This file is auto-generated from +// gpu/command_buffer/build_gles2_cmd_buffer.py +// DO NOT EDIT! #ifndef GPU_COMMAND_BUFFER_COMMON_GLES2_CMD_UTILS_AUTOGEN_H_ #define GPU_COMMAND_BUFFER_COMMON_GLES2_CMD_UTILS_AUTOGEN_H_ diff --git a/gpu/command_buffer/common/gles2_cmd_utils_implementation_autogen.h b/gpu/command_buffer/common/gles2_cmd_utils_implementation_autogen.h index 9007d14..9562636 100644 --- a/gpu/command_buffer/common/gles2_cmd_utils_implementation_autogen.h +++ b/gpu/command_buffer/common/gles2_cmd_utils_implementation_autogen.h @@ -2,7 +2,9 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -// This file is auto-generated. DO NOT EDIT! +// This file is auto-generated from +// gpu/command_buffer/build_gles2_cmd_buffer.py +// DO NOT EDIT! #ifndef GPU_COMMAND_BUFFER_COMMON_GLES2_CMD_UTILS_IMPLEMENTATION_AUTOGEN_H_ #define GPU_COMMAND_BUFFER_COMMON_GLES2_CMD_UTILS_IMPLEMENTATION_AUTOGEN_H_ diff --git a/gpu/command_buffer/service/gles2_cmd_decoder.cc b/gpu/command_buffer/service/gles2_cmd_decoder.cc index a237c0b..c0a60d2 100644 --- a/gpu/command_buffer/service/gles2_cmd_decoder.cc +++ b/gpu/command_buffer/service/gles2_cmd_decoder.cc @@ -6848,6 +6848,83 @@ error::Error GLES2DecoderImpl::HandleRequestExtensionCHROMIUM( return error::kNoError; } +error::Error GLES2DecoderImpl::HandleGetMultipleIntegervCHROMIUM( + uint32 immediate_data_size, const gles2::GetMultipleIntegervCHROMIUM& c) { + GLuint count = c.count; + uint32 pnames_size; + if (!SafeMultiplyUint32(count, sizeof(GLenum), &pnames_size)) { + return error::kOutOfBounds; + } + const GLenum* pnames = GetSharedMemoryAs<const GLenum*>( + c.pnames_shm_id, c.pnames_shm_offset, pnames_size); + if (pnames == NULL) { + return error::kOutOfBounds; + } + + // We have to copy them since we use them twice so the client + // can't change them between the time we validate them and the time we use + // them. + scoped_array<GLenum> enums(new GLenum[count]); + memcpy(enums.get(), pnames, pnames_size); + + // Count up the space needed for the result. + uint32 num_results = 0; + for (GLuint ii = 0; ii < count; ++ii) { + uint32 num = util_.GLGetNumValuesReturned(enums[ii]); + if (num == 0) { + SetGLError(GL_INVALID_ENUM, + "glGetMulitpleCHROMIUM: pname GL_INVALID_ENUM"); + return error::kNoError; + } + // Num will never be more than 4. + DCHECK_LE(num, 4u); + if (!SafeAdd(num_results, num, &num_results)) { + return error::kOutOfBounds; + } + } + + uint32 result_size = 0; + if (!SafeMultiplyUint32(num_results, sizeof(GLint), &result_size)) { + return error::kOutOfBounds; + } + + if (result_size != static_cast<uint32>(c.size)) { + SetGLError(GL_INVALID_VALUE, + "glGetMulitpleCHROMIUM: bad size GL_INVALID_VALUE"); + return error::kNoError; + } + + GLint* results = GetSharedMemoryAs<GLint*>( + c.results_shm_id, c.results_shm_offset, result_size); + if (results == NULL) { + return error::kOutOfBounds; + } + + // Check the results have been cleared in case the context was lost. + for (uint32 ii = 0; ii < num_results; ++ii) { + if (results[ii]) { + return error::kInvalidArguments; + } + } + + // Get each result. + GLint* start = results; + for (GLuint ii = 0; ii < count; ++ii) { + GLsizei num_written = 0; + if (!GetHelper(enums[ii], results, &num_written)) { + glGetIntegerv(enums[ii], results); + } + results += num_written; + } + + // Just to verify. Should this be a DCHECK? + if (results - start != num_results) { + return error::kOutOfBounds; + } + + return error::kNoError; +} + // Include the auto-generated part of this file. We split this because it means // we can easily edit the non-auto generated parts right here in this file // instead of having to edit some template or the code generator. diff --git a/gpu/command_buffer/service/gles2_cmd_decoder_autogen.h b/gpu/command_buffer/service/gles2_cmd_decoder_autogen.h index 9f7711a..89cf621 100644 --- a/gpu/command_buffer/service/gles2_cmd_decoder_autogen.h +++ b/gpu/command_buffer/service/gles2_cmd_decoder_autogen.h @@ -2,7 +2,9 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -// This file is auto-generated. DO NOT EDIT! +// This file is auto-generated from +// gpu/command_buffer/build_gles2_cmd_buffer.py +// DO NOT EDIT! // It is included by gles2_cmd_decoder.cc #ifndef GPU_COMMAND_BUFFER_SERVICE_GLES2_CMD_DECODER_AUTOGEN_H_ diff --git a/gpu/command_buffer/service/gles2_cmd_decoder_unittest.cc b/gpu/command_buffer/service/gles2_cmd_decoder_unittest.cc index 82d99e8..e84c93a 100644 --- a/gpu/command_buffer/service/gles2_cmd_decoder_unittest.cc +++ b/gpu/command_buffer/service/gles2_cmd_decoder_unittest.cc @@ -3883,6 +3883,136 @@ TEST_F(GLES2DecoderManualInitTest, PackedDepthStencilRenderbufferStencil) { EXPECT_EQ(0, result->GetData()[0]); } +TEST_F(GLES2DecoderTest, GetMultipleIntegervCHROMIUMValidArgs) { + const GLsizei kCount = 3; + GLenum* pnames = GetSharedMemoryAs<GLenum*>(); + pnames[0] = GL_DEPTH_WRITEMASK; + pnames[1] = GL_COLOR_WRITEMASK; + pnames[2] = GL_STENCIL_WRITEMASK; + GLint* results = + GetSharedMemoryAsWithOffset<GLint*>(sizeof(*pnames) * kCount); + + GLsizei num_results = 0; + for (GLsizei ii = 0; ii < kCount; ++ii) { + num_results += decoder_->GetGLES2Util()->GLGetNumValuesReturned(pnames[ii]); + } + const GLsizei result_size = num_results * sizeof(*results); + memset(results, 0, result_size); + + const GLint kSentinel = 0x12345678; + results[num_results] = kSentinel; + + GetMultipleIntegervCHROMIUM cmd; + cmd.Init( + kSharedMemoryId, kSharedMemoryOffset, kCount, + kSharedMemoryId, kSharedMemoryOffset + sizeof(*pnames) * kCount, + result_size); + + EXPECT_EQ(error::kNoError, ExecuteCmd(cmd)); + EXPECT_EQ(GL_NO_ERROR, GetGLError()); + EXPECT_EQ(1, results[0]); // Depth writemask + EXPECT_EQ(1, results[1]); // color writemask red + EXPECT_EQ(1, results[2]); // color writemask green + EXPECT_EQ(1, results[3]); // color writemask blue + EXPECT_EQ(1, results[4]); // color writemask alpha + EXPECT_EQ(-1, results[5]); // stencil writemask alpha + EXPECT_EQ(kSentinel, results[num_results]); // End of results +} + +TEST_F(GLES2DecoderTest, GetMultipleIntegervCHROMIUMInvalidArgs) { + const GLsizei kCount = 3; + // Offset the pnames because GLGetError will use the first uint32. + const uint32 kPnameOffset = sizeof(uint32); + const uint32 kResultsOffset = kPnameOffset + sizeof(GLint) * kCount; + GLenum* pnames = GetSharedMemoryAsWithOffset<GLenum*>(kPnameOffset); + pnames[0] = GL_DEPTH_WRITEMASK; + pnames[1] = GL_COLOR_WRITEMASK; + pnames[2] = GL_STENCIL_WRITEMASK; + GLint* results = GetSharedMemoryAsWithOffset<GLint*>(kResultsOffset); + + GLsizei num_results = 0; + for (GLsizei ii = 0; ii < kCount; ++ii) { + num_results += decoder_->GetGLES2Util()->GLGetNumValuesReturned(pnames[ii]); + } + const GLsizei result_size = num_results * sizeof(*results); + memset(results, 0, result_size); + + const GLint kSentinel = 0x12345678; + results[num_results] = kSentinel; + + GetMultipleIntegervCHROMIUM cmd; + // Check bad pnames pointer. + cmd.Init( + kInvalidSharedMemoryId, kSharedMemoryOffset + kPnameOffset, kCount, + kSharedMemoryId, kSharedMemoryOffset + kResultsOffset, + result_size); + EXPECT_EQ(error::kOutOfBounds, ExecuteCmd(cmd)); + EXPECT_EQ(GL_NO_ERROR, GetGLError()); + // Check bad pnames pointer. + cmd.Init( + kSharedMemoryId, kInvalidSharedMemoryOffset, kCount, + kSharedMemoryId, kSharedMemoryOffset + kResultsOffset, + result_size); + EXPECT_EQ(error::kOutOfBounds, ExecuteCmd(cmd)); + EXPECT_EQ(GL_NO_ERROR, GetGLError()); + // Check bad count. + cmd.Init( + kSharedMemoryId, kSharedMemoryOffset + kPnameOffset, -1, + kSharedMemoryId, kSharedMemoryOffset + kResultsOffset, + result_size); + EXPECT_EQ(error::kOutOfBounds, ExecuteCmd(cmd)); + EXPECT_EQ(GL_NO_ERROR, GetGLError()); + // Check bad results pointer. + cmd.Init( + kSharedMemoryId, kSharedMemoryOffset + kPnameOffset, kCount, + kInvalidSharedMemoryId, kSharedMemoryOffset + kResultsOffset, + result_size); + EXPECT_EQ(error::kOutOfBounds, ExecuteCmd(cmd)); + EXPECT_EQ(GL_NO_ERROR, GetGLError()); + // Check bad results pointer. + cmd.Init( + kSharedMemoryId, kSharedMemoryOffset + kPnameOffset, kCount, + kSharedMemoryId, kInvalidSharedMemoryOffset, + result_size); + EXPECT_EQ(error::kOutOfBounds, ExecuteCmd(cmd)); + EXPECT_EQ(GL_NO_ERROR, GetGLError()); + // Check bad size. + cmd.Init( + kSharedMemoryId, kSharedMemoryOffset + kPnameOffset, kCount, + kSharedMemoryId, kSharedMemoryOffset + kResultsOffset, + result_size + 1); + EXPECT_EQ(error::kNoError, ExecuteCmd(cmd)); + EXPECT_EQ(GL_INVALID_VALUE, GetGLError()); + // Check bad size. + cmd.Init( + kSharedMemoryId, kSharedMemoryOffset + kPnameOffset, kCount, + kSharedMemoryId, kSharedMemoryOffset + kResultsOffset, + result_size - 1); + EXPECT_EQ(error::kNoError, ExecuteCmd(cmd)); + EXPECT_EQ(GL_INVALID_VALUE, GetGLError()); + // Check bad enum. + cmd.Init( + kSharedMemoryId, kSharedMemoryOffset + kPnameOffset, kCount, + kSharedMemoryId, kSharedMemoryOffset + kResultsOffset, + result_size); + GLenum temp = pnames[2]; + pnames[2] = GL_TRUE; + EXPECT_EQ(error::kNoError, ExecuteCmd(cmd)); + EXPECT_EQ(GL_INVALID_ENUM, GetGLError()); + pnames[2] = temp; + // Check results area has not been cleared by client. + results[1] = 1; + EXPECT_EQ(error::kInvalidArguments, ExecuteCmd(cmd)); + // Check buffer is what we expect + EXPECT_EQ(0, results[0]); + EXPECT_EQ(1, results[1]); + EXPECT_EQ(0, results[2]); + EXPECT_EQ(0, results[3]); + EXPECT_EQ(0, results[4]); + EXPECT_EQ(0, results[5]); + EXPECT_EQ(kSentinel, results[num_results]); // End of results +} + // TODO(gman): BufferData // TODO(gman): BufferDataImmediate 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 58f5a86..fe90c47 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 @@ -2,7 +2,9 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -// This file is auto-generated. DO NOT EDIT! +// This file is auto-generated from +// gpu/command_buffer/build_gles2_cmd_buffer.py +// DO NOT EDIT! // It is included by gles2_cmd_decoder_unittest_1.cc #ifndef 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 8f93103..c5f5594 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 @@ -2,7 +2,9 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -// This file is auto-generated. DO NOT EDIT! +// This file is auto-generated from +// gpu/command_buffer/build_gles2_cmd_buffer.py +// DO NOT EDIT! // It is included by gles2_cmd_decoder_unittest_2.cc #ifndef GPU_COMMAND_BUFFER_SERVICE_GLES2_CMD_DECODER_UNITTEST_2_AUTOGEN_H_ diff --git a/gpu/command_buffer/service/gles2_cmd_decoder_unittest_3_autogen.h b/gpu/command_buffer/service/gles2_cmd_decoder_unittest_3_autogen.h index 94c5ffc..95ed93f 100644 --- a/gpu/command_buffer/service/gles2_cmd_decoder_unittest_3_autogen.h +++ b/gpu/command_buffer/service/gles2_cmd_decoder_unittest_3_autogen.h @@ -2,7 +2,9 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -// This file is auto-generated. DO NOT EDIT! +// This file is auto-generated from +// gpu/command_buffer/build_gles2_cmd_buffer.py +// DO NOT EDIT! // It is included by gles2_cmd_decoder_unittest_3.cc #ifndef GPU_COMMAND_BUFFER_SERVICE_GLES2_CMD_DECODER_UNITTEST_3_AUTOGEN_H_ @@ -11,5 +13,7 @@ // TODO(gman): WaitLatchCHROMIUM // TODO(gman): SetSurfaceCHROMIUM +// TODO(gman): GetMultipleIntegervCHROMIUM + #endif // GPU_COMMAND_BUFFER_SERVICE_GLES2_CMD_DECODER_UNITTEST_3_AUTOGEN_H_ diff --git a/gpu/command_buffer/service/gles2_cmd_validation_autogen.h b/gpu/command_buffer/service/gles2_cmd_validation_autogen.h index c7def35..fa02ff5 100644 --- a/gpu/command_buffer/service/gles2_cmd_validation_autogen.h +++ b/gpu/command_buffer/service/gles2_cmd_validation_autogen.h @@ -2,7 +2,9 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -// This file is auto-generated. DO NOT EDIT! +// This file is auto-generated from +// gpu/command_buffer/build_gles2_cmd_buffer.py +// DO NOT EDIT! #ifndef GPU_COMMAND_BUFFER_SERVICE_GLES2_CMD_VALIDATION_AUTOGEN_H_ #define GPU_COMMAND_BUFFER_SERVICE_GLES2_CMD_VALIDATION_AUTOGEN_H_ 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 c3cd9d2..e7f7392 100644 --- a/gpu/command_buffer/service/gles2_cmd_validation_implementation_autogen.h +++ b/gpu/command_buffer/service/gles2_cmd_validation_implementation_autogen.h @@ -2,7 +2,9 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -// This file is auto-generated. DO NOT EDIT! +// This file is auto-generated from +// gpu/command_buffer/build_gles2_cmd_buffer.py +// DO NOT EDIT! #ifndef GPU_COMMAND_BUFFER_SERVICE_GLES2_CMD_VALIDATION_IMPLEMENTATION_AUTOGEN_H_ // NOLINT #define GPU_COMMAND_BUFFER_SERVICE_GLES2_CMD_VALIDATION_IMPLEMENTATION_AUTOGEN_H_ // NOLINT |