OLD | NEW |
1 // Copyright (c) 2015 The Chromium Authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "gpu/command_buffer/client/program_info_manager.h" | 5 #include "gpu/command_buffer/client/program_info_manager.h" |
6 #include "testing/gtest/include/gtest/gtest.h" | 6 #include "testing/gtest/include/gtest/gtest.h" |
7 | 7 |
8 namespace { | 8 namespace { |
9 | 9 |
10 uint32 ComputeOffset(const void* start, const void* position) { | 10 uint32 ComputeOffset(const void* start, const void* position) { |
11 return static_cast<const uint8*>(position) - | 11 return static_cast<const uint8*>(position) - |
12 static_cast<const uint8*>(start); | 12 static_cast<const uint8*>(start); |
13 } | 13 } |
14 | 14 |
| 15 const GLuint kClientProgramId = 321; |
| 16 |
15 } // namespace anonymous | 17 } // namespace anonymous |
16 | 18 |
17 namespace gpu { | 19 namespace gpu { |
18 namespace gles2 { | 20 namespace gles2 { |
19 | 21 |
20 class ProgramInfoManagerTest : public testing::Test { | 22 class ProgramInfoManagerTest : public testing::Test { |
21 public: | 23 public: |
22 ProgramInfoManagerTest() {} | 24 ProgramInfoManagerTest() {} |
23 ~ProgramInfoManagerTest() override {} | 25 ~ProgramInfoManagerTest() override {} |
24 | 26 |
25 protected: | 27 protected: |
26 void SetUp() override {} | 28 typedef ProgramInfoManager::Program Program; |
27 | 29 |
28 void TearDown() override {} | 30 struct UniformBlocksData { |
29 }; | |
30 | |
31 TEST_F(ProgramInfoManagerTest, UpdateES3UniformBlocks) { | |
32 struct Data { | |
33 UniformBlocksHeader header; | 31 UniformBlocksHeader header; |
34 UniformBlockInfo entry[2]; | 32 UniformBlockInfo entry[2]; |
35 char name0[4]; | 33 char name0[4]; |
36 uint32_t indices0[2]; | 34 uint32_t indices0[2]; |
37 char name1[8]; | 35 char name1[8]; |
38 uint32_t indices1[1]; | 36 uint32_t indices1[1]; |
39 }; | 37 }; |
40 Data data; | |
41 // The names needs to be of size 4*k-1 to avoid padding in the struct Data. | |
42 // This is a testing only problem. | |
43 const char* kName[] = { "cow", "chicken" }; | |
44 const uint32_t kIndices0[] = { 1, 2 }; | |
45 const uint32_t kIndices1[] = { 3 }; | |
46 const uint32_t* kIndices[] = { kIndices0, kIndices1 }; | |
47 data.header.num_uniform_blocks = 2; | |
48 data.entry[0].binding = 0; | |
49 data.entry[0].data_size = 8; | |
50 data.entry[0].name_offset = ComputeOffset(&data, data.name0); | |
51 data.entry[0].name_length = arraysize(data.name0); | |
52 data.entry[0].active_uniforms = arraysize(data.indices0); | |
53 data.entry[0].active_uniform_offset = ComputeOffset(&data, data.indices0); | |
54 data.entry[0].referenced_by_vertex_shader = static_cast<uint32_t>(true); | |
55 data.entry[0].referenced_by_fragment_shader = static_cast<uint32_t>(false); | |
56 data.entry[1].binding = 1; | |
57 data.entry[1].data_size = 4; | |
58 data.entry[1].name_offset = ComputeOffset(&data, data.name1); | |
59 data.entry[1].name_length = arraysize(data.name1); | |
60 data.entry[1].active_uniforms = arraysize(data.indices1); | |
61 data.entry[1].active_uniform_offset = ComputeOffset(&data, data.indices1); | |
62 data.entry[1].referenced_by_vertex_shader = static_cast<uint32_t>(false); | |
63 data.entry[1].referenced_by_fragment_shader = static_cast<uint32_t>(true); | |
64 memcpy(data.name0, kName[0], arraysize(data.name0)); | |
65 data.indices0[0] = kIndices[0][0]; | |
66 data.indices0[1] = kIndices[0][1]; | |
67 memcpy(data.name1, kName[1], arraysize(data.name1)); | |
68 data.indices1[0] = kIndices[1][0]; | |
69 | 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 }; |
70 std::vector<int8> result(sizeof(data)); | 92 std::vector<int8> result(sizeof(data)); |
71 memcpy(&result[0], &data, 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)); |
72 | 97 |
73 ProgramInfoManager::Program program; | |
74 EXPECT_FALSE(program.IsCached(ProgramInfoManager::kES3UniformBlocks)); | |
75 program.UpdateES3UniformBlocks(result); | |
76 EXPECT_TRUE(program.IsCached(ProgramInfoManager::kES3UniformBlocks)); | |
77 GLint uniform_block_count = 0; | 98 GLint uniform_block_count = 0; |
78 EXPECT_TRUE(program.GetProgramiv( | 99 EXPECT_TRUE(program_->GetProgramiv( |
79 GL_ACTIVE_UNIFORM_BLOCKS, &uniform_block_count)); | 100 GL_ACTIVE_UNIFORM_BLOCKS, &uniform_block_count)); |
80 EXPECT_EQ(data.header.num_uniform_blocks, | 101 EXPECT_EQ(data.header.num_uniform_blocks, |
81 static_cast<uint32_t>(uniform_block_count)); | 102 static_cast<uint32_t>(uniform_block_count)); |
82 GLint max_name_length = 0; | 103 GLint max_name_length = 0; |
83 EXPECT_TRUE(program.GetProgramiv( | 104 EXPECT_TRUE(program_->GetProgramiv( |
84 GL_ACTIVE_UNIFORM_BLOCK_MAX_NAME_LENGTH, &max_name_length)); | 105 GL_ACTIVE_UNIFORM_BLOCK_MAX_NAME_LENGTH, &max_name_length)); |
85 for (uint32_t ii = 0; ii < data.header.num_uniform_blocks; ++ii) { | 106 for (uint32_t ii = 0; ii < data.header.num_uniform_blocks; ++ii) { |
86 EXPECT_EQ(ii, program.GetUniformBlockIndex(kName[ii])); | 107 EXPECT_EQ(ii, program_->GetUniformBlockIndex(kName[ii])); |
87 const ProgramInfoManager::Program::UniformBlock* info = | 108 const Program::UniformBlock* info = program_->GetUniformBlock(ii); |
88 program.GetUniformBlock(ii); | |
89 EXPECT_TRUE(info != NULL); | 109 EXPECT_TRUE(info != NULL); |
90 EXPECT_EQ(data.entry[ii].binding, info->binding); | 110 EXPECT_EQ(data.entry[ii].binding, info->binding); |
91 EXPECT_EQ(data.entry[ii].data_size, info->data_size); | 111 EXPECT_EQ(data.entry[ii].data_size, info->data_size); |
92 EXPECT_EQ(data.entry[ii].active_uniforms, | 112 EXPECT_EQ(data.entry[ii].active_uniforms, |
93 info->active_uniform_indices.size()); | 113 info->active_uniform_indices.size()); |
94 for (uint32_t uu = 0; uu < data.entry[ii].active_uniforms; ++uu) { | 114 for (uint32_t uu = 0; uu < data.entry[ii].active_uniforms; ++uu) { |
95 EXPECT_EQ(kIndices[ii][uu], info->active_uniform_indices[uu]); | 115 EXPECT_EQ(kIndices[ii][uu], info->active_uniform_indices[uu]); |
96 } | 116 } |
97 EXPECT_EQ(data.entry[ii].referenced_by_vertex_shader, | 117 EXPECT_EQ(data.entry[ii].referenced_by_vertex_shader, |
98 static_cast<GLboolean>(info->referenced_by_vertex_shader)); | 118 static_cast<GLboolean>(info->referenced_by_vertex_shader)); |
99 EXPECT_EQ(data.entry[ii].referenced_by_fragment_shader, | 119 EXPECT_EQ(data.entry[ii].referenced_by_fragment_shader, |
100 static_cast<GLboolean>(info->referenced_by_fragment_shader)); | 120 static_cast<GLboolean>(info->referenced_by_fragment_shader)); |
101 EXPECT_EQ(kName[ii], info->name); | 121 EXPECT_EQ(kName[ii], info->name); |
102 EXPECT_GE(max_name_length, static_cast<GLint>(info->name.size()) + 1); | 122 EXPECT_GE(max_name_length, static_cast<GLint>(info->name.size()) + 1); |
103 } | 123 } |
104 | 124 |
105 EXPECT_EQ(GL_INVALID_INDEX, program.GetUniformBlockIndex("BadName")); | 125 EXPECT_EQ(GL_INVALID_INDEX, program_->GetUniformBlockIndex("BadName")); |
106 EXPECT_EQ(NULL, program.GetUniformBlock(data.header.num_uniform_blocks)); | 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]); |
107 } | 180 } |
108 | 181 |
109 } // namespace gles2 | 182 } // namespace gles2 |
110 } // namespace gpu | 183 } // namespace gpu |
111 | 184 |
OLD | NEW |