OLD | NEW |
(Empty) | |
| 1 // Copyright (c) 2015 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. |
| 4 |
| 5 #include "gpu/command_buffer/client/program_info_manager.h" |
| 6 #include "testing/gtest/include/gtest/gtest.h" |
| 7 |
| 8 namespace { |
| 9 |
| 10 uint32 ComputeOffset(const void* start, const void* position) { |
| 11 return static_cast<const uint8*>(position) - |
| 12 static_cast<const uint8*>(start); |
| 13 } |
| 14 |
| 15 const GLuint kClientProgramId = 321; |
| 16 |
| 17 } // namespace anonymous |
| 18 |
| 19 namespace gpu { |
| 20 namespace gles2 { |
| 21 |
| 22 class ProgramInfoManagerTest : public testing::Test { |
| 23 public: |
| 24 ProgramInfoManagerTest() {} |
| 25 ~ProgramInfoManagerTest() override {} |
| 26 |
| 27 protected: |
| 28 typedef ProgramInfoManager::Program Program; |
| 29 |
| 30 struct UniformBlocksData { |
| 31 UniformBlocksHeader header; |
| 32 UniformBlockInfo entry[2]; |
| 33 char name0[4]; |
| 34 uint32_t indices0[2]; |
| 35 char name1[8]; |
| 36 uint32_t indices1[1]; |
| 37 }; |
| 38 |
| 39 void SetUp() override { |
| 40 program_info_manager_.reset(new ProgramInfoManager); |
| 41 program_info_manager_->CreateInfo(kClientProgramId); |
| 42 { |
| 43 base::AutoLock auto_lock(program_info_manager_->lock_); |
| 44 program_ = program_info_manager_->GetProgramInfo( |
| 45 NULL, kClientProgramId, ProgramInfoManager::kNone); |
| 46 ASSERT_TRUE(program_ != NULL); |
| 47 } |
| 48 } |
| 49 |
| 50 void TearDown() override {} |
| 51 |
| 52 void SetupUniformBlocksData(UniformBlocksData* data) { |
| 53 // The names needs to be of size 4*k-1 to avoid padding in the struct Data. |
| 54 // This is a testing only problem. |
| 55 const char* kName[] = { "cow", "chicken" }; |
| 56 const uint32_t kIndices0[] = { 1, 2 }; |
| 57 const uint32_t kIndices1[] = { 3 }; |
| 58 const uint32_t* kIndices[] = { kIndices0, kIndices1 }; |
| 59 data->header.num_uniform_blocks = 2; |
| 60 data->entry[0].binding = 0; |
| 61 data->entry[0].data_size = 8; |
| 62 data->entry[0].name_offset = ComputeOffset(data, data->name0); |
| 63 data->entry[0].name_length = arraysize(data->name0); |
| 64 data->entry[0].active_uniforms = arraysize(data->indices0); |
| 65 data->entry[0].active_uniform_offset = ComputeOffset(data, data->indices0); |
| 66 data->entry[0].referenced_by_vertex_shader = static_cast<uint32_t>(true); |
| 67 data->entry[0].referenced_by_fragment_shader = static_cast<uint32_t>(false); |
| 68 data->entry[1].binding = 1; |
| 69 data->entry[1].data_size = 4; |
| 70 data->entry[1].name_offset = ComputeOffset(data, data->name1); |
| 71 data->entry[1].name_length = arraysize(data->name1); |
| 72 data->entry[1].active_uniforms = arraysize(data->indices1); |
| 73 data->entry[1].active_uniform_offset = ComputeOffset(data, data->indices1); |
| 74 data->entry[1].referenced_by_vertex_shader = static_cast<uint32_t>(false); |
| 75 data->entry[1].referenced_by_fragment_shader = static_cast<uint32_t>(true); |
| 76 memcpy(data->name0, kName[0], arraysize(data->name0)); |
| 77 data->indices0[0] = kIndices[0][0]; |
| 78 data->indices0[1] = kIndices[0][1]; |
| 79 memcpy(data->name1, kName[1], arraysize(data->name1)); |
| 80 data->indices1[0] = kIndices[1][0]; |
| 81 } |
| 82 |
| 83 scoped_ptr<ProgramInfoManager> program_info_manager_; |
| 84 Program* program_; |
| 85 }; |
| 86 |
| 87 TEST_F(ProgramInfoManagerTest, UpdateES3UniformBlocks) { |
| 88 UniformBlocksData data; |
| 89 SetupUniformBlocksData(&data); |
| 90 const std::string kName[] = { data.name0, data.name1 }; |
| 91 const uint32_t* kIndices[] = { data.indices0, data.indices1 }; |
| 92 std::vector<int8> result(sizeof(data)); |
| 93 memcpy(&result[0], &data, sizeof(data)); |
| 94 EXPECT_FALSE(program_->IsCached(ProgramInfoManager::kES3UniformBlocks)); |
| 95 program_->UpdateES3UniformBlocks(result); |
| 96 EXPECT_TRUE(program_->IsCached(ProgramInfoManager::kES3UniformBlocks)); |
| 97 |
| 98 GLint uniform_block_count = 0; |
| 99 EXPECT_TRUE(program_->GetProgramiv( |
| 100 GL_ACTIVE_UNIFORM_BLOCKS, &uniform_block_count)); |
| 101 EXPECT_EQ(data.header.num_uniform_blocks, |
| 102 static_cast<uint32_t>(uniform_block_count)); |
| 103 GLint max_name_length = 0; |
| 104 EXPECT_TRUE(program_->GetProgramiv( |
| 105 GL_ACTIVE_UNIFORM_BLOCK_MAX_NAME_LENGTH, &max_name_length)); |
| 106 for (uint32_t ii = 0; ii < data.header.num_uniform_blocks; ++ii) { |
| 107 EXPECT_EQ(ii, program_->GetUniformBlockIndex(kName[ii])); |
| 108 const Program::UniformBlock* info = program_->GetUniformBlock(ii); |
| 109 EXPECT_TRUE(info != NULL); |
| 110 EXPECT_EQ(data.entry[ii].binding, info->binding); |
| 111 EXPECT_EQ(data.entry[ii].data_size, info->data_size); |
| 112 EXPECT_EQ(data.entry[ii].active_uniforms, |
| 113 info->active_uniform_indices.size()); |
| 114 for (uint32_t uu = 0; uu < data.entry[ii].active_uniforms; ++uu) { |
| 115 EXPECT_EQ(kIndices[ii][uu], info->active_uniform_indices[uu]); |
| 116 } |
| 117 EXPECT_EQ(data.entry[ii].referenced_by_vertex_shader, |
| 118 static_cast<GLboolean>(info->referenced_by_vertex_shader)); |
| 119 EXPECT_EQ(data.entry[ii].referenced_by_fragment_shader, |
| 120 static_cast<GLboolean>(info->referenced_by_fragment_shader)); |
| 121 EXPECT_EQ(kName[ii], info->name); |
| 122 EXPECT_GE(max_name_length, static_cast<GLint>(info->name.size()) + 1); |
| 123 } |
| 124 |
| 125 EXPECT_EQ(GL_INVALID_INDEX, program_->GetUniformBlockIndex("BadName")); |
| 126 EXPECT_EQ(NULL, program_->GetUniformBlock(data.header.num_uniform_blocks)); |
| 127 } |
| 128 |
| 129 TEST_F(ProgramInfoManagerTest, GetUniformBlockIndexCached) { |
| 130 UniformBlocksData data; |
| 131 SetupUniformBlocksData(&data); |
| 132 std::vector<int8> result(sizeof(data)); |
| 133 memcpy(&result[0], &data, sizeof(data)); |
| 134 program_->UpdateES3UniformBlocks(result); |
| 135 |
| 136 EXPECT_EQ(0u, program_info_manager_->GetUniformBlockIndex( |
| 137 NULL, kClientProgramId, data.name0)); |
| 138 EXPECT_EQ(1u, program_info_manager_->GetUniformBlockIndex( |
| 139 NULL, kClientProgramId, data.name1)); |
| 140 EXPECT_EQ(GL_INVALID_INDEX, program_info_manager_->GetUniformBlockIndex( |
| 141 NULL, kClientProgramId, "BadName")); |
| 142 } |
| 143 |
| 144 TEST_F(ProgramInfoManagerTest, GetActiveUniformBlockNameCached) { |
| 145 UniformBlocksData data; |
| 146 SetupUniformBlocksData(&data); |
| 147 std::vector<int8> result(sizeof(data)); |
| 148 memcpy(&result[0], &data, sizeof(data)); |
| 149 program_->UpdateES3UniformBlocks(result); |
| 150 |
| 151 GLsizei buf_size = std::max(strlen(data.name0), strlen(data.name1)) + 1; |
| 152 std::vector<char> buffer(buf_size); |
| 153 GLsizei length = 0; |
| 154 EXPECT_EQ(true, program_info_manager_->GetActiveUniformBlockName( |
| 155 NULL, kClientProgramId, 0, buf_size, &length, &buffer[0])); |
| 156 EXPECT_EQ(static_cast<GLsizei>(strlen(data.name0)), length); |
| 157 EXPECT_STREQ(data.name0, &buffer[0]); |
| 158 |
| 159 EXPECT_EQ(true, program_info_manager_->GetActiveUniformBlockName( |
| 160 NULL, kClientProgramId, 1, buf_size, &length, &buffer[0])); |
| 161 EXPECT_EQ(static_cast<GLsizei>(strlen(data.name1)), length); |
| 162 EXPECT_STREQ(data.name1, &buffer[0]); |
| 163 |
| 164 // Test length == NULL. |
| 165 EXPECT_EQ(true, program_info_manager_->GetActiveUniformBlockName( |
| 166 NULL, kClientProgramId, 0, buf_size, NULL, &buffer[0])); |
| 167 EXPECT_STREQ(data.name0, &buffer[0]); |
| 168 |
| 169 // Test buffer == NULL. |
| 170 EXPECT_EQ(true, program_info_manager_->GetActiveUniformBlockName( |
| 171 NULL, kClientProgramId, 0, buf_size, &length, NULL)); |
| 172 EXPECT_EQ(0, length); |
| 173 |
| 174 // Test buf_size smaller than string size. |
| 175 buf_size = strlen(data.name0); |
| 176 EXPECT_EQ(true, program_info_manager_->GetActiveUniformBlockName( |
| 177 NULL, kClientProgramId, 0, buf_size, &length, &buffer[0])); |
| 178 EXPECT_EQ(buf_size, length + 1); |
| 179 EXPECT_STREQ(std::string(data.name0).substr(0, length).c_str(), &buffer[0]); |
| 180 } |
| 181 |
| 182 } // namespace gles2 |
| 183 } // namespace gpu |
| 184 |
OLD | NEW |