Index: gpu/command_buffer/client/program_info_manager_unittest.cc |
diff --git a/gpu/command_buffer/client/program_info_manager_unittest.cc b/gpu/command_buffer/client/program_info_manager_unittest.cc |
new file mode 100644 |
index 0000000000000000000000000000000000000000..6b0576cf82c11ca727ad2d85f40a8c414aaae509 |
--- /dev/null |
+++ b/gpu/command_buffer/client/program_info_manager_unittest.cc |
@@ -0,0 +1,184 @@ |
+// Copyright (c) 2015 The Chromium Authors. All rights reserved. |
+// Use of this source code is governed by a BSD-style license that can be |
+// found in the LICENSE file. |
+ |
+#include "gpu/command_buffer/client/program_info_manager.h" |
+#include "testing/gtest/include/gtest/gtest.h" |
+ |
+namespace { |
+ |
+uint32 ComputeOffset(const void* start, const void* position) { |
+ return static_cast<const uint8*>(position) - |
+ static_cast<const uint8*>(start); |
+} |
+ |
+const GLuint kClientProgramId = 321; |
+ |
+} // namespace anonymous |
+ |
+namespace gpu { |
+namespace gles2 { |
+ |
+class ProgramInfoManagerTest : public testing::Test { |
+ public: |
+ ProgramInfoManagerTest() {} |
+ ~ProgramInfoManagerTest() override {} |
+ |
+ protected: |
+ typedef ProgramInfoManager::Program Program; |
+ |
+ struct UniformBlocksData { |
+ UniformBlocksHeader header; |
+ UniformBlockInfo entry[2]; |
+ char name0[4]; |
+ uint32_t indices0[2]; |
+ char name1[8]; |
+ uint32_t indices1[1]; |
+ }; |
+ |
+ void SetUp() override { |
+ program_info_manager_.reset(new ProgramInfoManager); |
+ program_info_manager_->CreateInfo(kClientProgramId); |
+ { |
+ base::AutoLock auto_lock(program_info_manager_->lock_); |
+ program_ = program_info_manager_->GetProgramInfo( |
+ NULL, kClientProgramId, ProgramInfoManager::kNone); |
+ ASSERT_TRUE(program_ != NULL); |
+ } |
+ } |
+ |
+ void TearDown() override {} |
+ |
+ void SetupUniformBlocksData(UniformBlocksData* data) { |
+ // The names needs to be of size 4*k-1 to avoid padding in the struct Data. |
+ // This is a testing only problem. |
+ const char* kName[] = { "cow", "chicken" }; |
+ const uint32_t kIndices0[] = { 1, 2 }; |
+ const uint32_t kIndices1[] = { 3 }; |
+ const uint32_t* kIndices[] = { kIndices0, kIndices1 }; |
+ data->header.num_uniform_blocks = 2; |
+ data->entry[0].binding = 0; |
+ data->entry[0].data_size = 8; |
+ data->entry[0].name_offset = ComputeOffset(data, data->name0); |
+ data->entry[0].name_length = arraysize(data->name0); |
+ data->entry[0].active_uniforms = arraysize(data->indices0); |
+ data->entry[0].active_uniform_offset = ComputeOffset(data, data->indices0); |
+ data->entry[0].referenced_by_vertex_shader = static_cast<uint32_t>(true); |
+ data->entry[0].referenced_by_fragment_shader = static_cast<uint32_t>(false); |
+ data->entry[1].binding = 1; |
+ data->entry[1].data_size = 4; |
+ data->entry[1].name_offset = ComputeOffset(data, data->name1); |
+ data->entry[1].name_length = arraysize(data->name1); |
+ data->entry[1].active_uniforms = arraysize(data->indices1); |
+ data->entry[1].active_uniform_offset = ComputeOffset(data, data->indices1); |
+ data->entry[1].referenced_by_vertex_shader = static_cast<uint32_t>(false); |
+ data->entry[1].referenced_by_fragment_shader = static_cast<uint32_t>(true); |
+ memcpy(data->name0, kName[0], arraysize(data->name0)); |
+ data->indices0[0] = kIndices[0][0]; |
+ data->indices0[1] = kIndices[0][1]; |
+ memcpy(data->name1, kName[1], arraysize(data->name1)); |
+ data->indices1[0] = kIndices[1][0]; |
+ } |
+ |
+ scoped_ptr<ProgramInfoManager> program_info_manager_; |
+ Program* program_; |
+}; |
+ |
+TEST_F(ProgramInfoManagerTest, UpdateES3UniformBlocks) { |
+ UniformBlocksData data; |
+ SetupUniformBlocksData(&data); |
+ const std::string kName[] = { data.name0, data.name1 }; |
+ const uint32_t* kIndices[] = { data.indices0, data.indices1 }; |
+ std::vector<int8> result(sizeof(data)); |
+ memcpy(&result[0], &data, sizeof(data)); |
+ EXPECT_FALSE(program_->IsCached(ProgramInfoManager::kES3UniformBlocks)); |
+ program_->UpdateES3UniformBlocks(result); |
+ EXPECT_TRUE(program_->IsCached(ProgramInfoManager::kES3UniformBlocks)); |
+ |
+ GLint uniform_block_count = 0; |
+ EXPECT_TRUE(program_->GetProgramiv( |
+ GL_ACTIVE_UNIFORM_BLOCKS, &uniform_block_count)); |
+ EXPECT_EQ(data.header.num_uniform_blocks, |
+ static_cast<uint32_t>(uniform_block_count)); |
+ GLint max_name_length = 0; |
+ EXPECT_TRUE(program_->GetProgramiv( |
+ GL_ACTIVE_UNIFORM_BLOCK_MAX_NAME_LENGTH, &max_name_length)); |
+ for (uint32_t ii = 0; ii < data.header.num_uniform_blocks; ++ii) { |
+ EXPECT_EQ(ii, program_->GetUniformBlockIndex(kName[ii])); |
+ const Program::UniformBlock* info = program_->GetUniformBlock(ii); |
+ EXPECT_TRUE(info != NULL); |
+ EXPECT_EQ(data.entry[ii].binding, info->binding); |
+ EXPECT_EQ(data.entry[ii].data_size, info->data_size); |
+ EXPECT_EQ(data.entry[ii].active_uniforms, |
+ info->active_uniform_indices.size()); |
+ for (uint32_t uu = 0; uu < data.entry[ii].active_uniforms; ++uu) { |
+ EXPECT_EQ(kIndices[ii][uu], info->active_uniform_indices[uu]); |
+ } |
+ EXPECT_EQ(data.entry[ii].referenced_by_vertex_shader, |
+ static_cast<GLboolean>(info->referenced_by_vertex_shader)); |
+ EXPECT_EQ(data.entry[ii].referenced_by_fragment_shader, |
+ static_cast<GLboolean>(info->referenced_by_fragment_shader)); |
+ EXPECT_EQ(kName[ii], info->name); |
+ EXPECT_GE(max_name_length, static_cast<GLint>(info->name.size()) + 1); |
+ } |
+ |
+ EXPECT_EQ(GL_INVALID_INDEX, program_->GetUniformBlockIndex("BadName")); |
+ EXPECT_EQ(NULL, program_->GetUniformBlock(data.header.num_uniform_blocks)); |
+} |
+ |
+TEST_F(ProgramInfoManagerTest, GetUniformBlockIndexCached) { |
+ UniformBlocksData data; |
+ SetupUniformBlocksData(&data); |
+ std::vector<int8> result(sizeof(data)); |
+ memcpy(&result[0], &data, sizeof(data)); |
+ program_->UpdateES3UniformBlocks(result); |
+ |
+ EXPECT_EQ(0u, program_info_manager_->GetUniformBlockIndex( |
+ NULL, kClientProgramId, data.name0)); |
+ EXPECT_EQ(1u, program_info_manager_->GetUniformBlockIndex( |
+ NULL, kClientProgramId, data.name1)); |
+ EXPECT_EQ(GL_INVALID_INDEX, program_info_manager_->GetUniformBlockIndex( |
+ NULL, kClientProgramId, "BadName")); |
+} |
+ |
+TEST_F(ProgramInfoManagerTest, GetActiveUniformBlockNameCached) { |
+ UniformBlocksData data; |
+ SetupUniformBlocksData(&data); |
+ std::vector<int8> result(sizeof(data)); |
+ memcpy(&result[0], &data, sizeof(data)); |
+ program_->UpdateES3UniformBlocks(result); |
+ |
+ GLsizei buf_size = std::max(strlen(data.name0), strlen(data.name1)) + 1; |
+ std::vector<char> buffer(buf_size); |
+ GLsizei length = 0; |
+ EXPECT_EQ(true, program_info_manager_->GetActiveUniformBlockName( |
+ NULL, kClientProgramId, 0, buf_size, &length, &buffer[0])); |
+ EXPECT_EQ(static_cast<GLsizei>(strlen(data.name0)), length); |
+ EXPECT_STREQ(data.name0, &buffer[0]); |
+ |
+ EXPECT_EQ(true, program_info_manager_->GetActiveUniformBlockName( |
+ NULL, kClientProgramId, 1, buf_size, &length, &buffer[0])); |
+ EXPECT_EQ(static_cast<GLsizei>(strlen(data.name1)), length); |
+ EXPECT_STREQ(data.name1, &buffer[0]); |
+ |
+ // Test length == NULL. |
+ EXPECT_EQ(true, program_info_manager_->GetActiveUniformBlockName( |
+ NULL, kClientProgramId, 0, buf_size, NULL, &buffer[0])); |
+ EXPECT_STREQ(data.name0, &buffer[0]); |
+ |
+ // Test buffer == NULL. |
+ EXPECT_EQ(true, program_info_manager_->GetActiveUniformBlockName( |
+ NULL, kClientProgramId, 0, buf_size, &length, NULL)); |
+ EXPECT_EQ(0, length); |
+ |
+ // Test buf_size smaller than string size. |
+ buf_size = strlen(data.name0); |
+ EXPECT_EQ(true, program_info_manager_->GetActiveUniformBlockName( |
+ NULL, kClientProgramId, 0, buf_size, &length, &buffer[0])); |
+ EXPECT_EQ(buf_size, length + 1); |
+ EXPECT_STREQ(std::string(data.name0).substr(0, length).c_str(), &buffer[0]); |
+} |
+ |
+} // namespace gles2 |
+} // namespace gpu |
+ |