summaryrefslogtreecommitdiffstats
path: root/gpu
diff options
context:
space:
mode:
authorgman@chromium.org <gman@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2011-06-27 22:34:47 +0000
committergman@chromium.org <gman@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2011-06-27 22:34:47 +0000
commit40c7ee4e84ba84f73b85521b47fe33e866c1d2da (patch)
treed2589e6da164405649f2818a0e45c083488a5b23 /gpu
parentc66019913aa4948835a24ca0f9feccb63003a6d7 (diff)
downloadchromium_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')
-rw-r--r--gpu/GLES2/gl2ext.h17
-rwxr-xr-xgpu/command_buffer/build_gles2_cmd_buffer.py9
-rw-r--r--gpu/command_buffer/client/gles2_c_lib_autogen.h9
-rw-r--r--gpu/command_buffer/client/gles2_cmd_helper_autogen.h14
-rw-r--r--gpu/command_buffer/client/gles2_implementation.cc55
-rw-r--r--gpu/command_buffer/client/gles2_implementation_autogen.h7
-rw-r--r--gpu/command_buffer/client/gles2_implementation_unittest.cc117
-rw-r--r--gpu/command_buffer/common/gles2_cmd_format_autogen.h66
-rw-r--r--gpu/command_buffer/common/gles2_cmd_format_test_autogen.h27
-rw-r--r--gpu/command_buffer/common/gles2_cmd_ids_autogen.h5
-rw-r--r--gpu/command_buffer/common/gles2_cmd_utils_autogen.h4
-rw-r--r--gpu/command_buffer/common/gles2_cmd_utils_implementation_autogen.h4
-rw-r--r--gpu/command_buffer/service/gles2_cmd_decoder.cc77
-rw-r--r--gpu/command_buffer/service/gles2_cmd_decoder_autogen.h4
-rw-r--r--gpu/command_buffer/service/gles2_cmd_decoder_unittest.cc130
-rw-r--r--gpu/command_buffer/service/gles2_cmd_decoder_unittest_1_autogen.h4
-rw-r--r--gpu/command_buffer/service/gles2_cmd_decoder_unittest_2_autogen.h4
-rw-r--r--gpu/command_buffer/service/gles2_cmd_decoder_unittest_3_autogen.h6
-rw-r--r--gpu/command_buffer/service/gles2_cmd_validation_autogen.h4
-rw-r--r--gpu/command_buffer/service/gles2_cmd_validation_implementation_autogen.h4
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