Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(32)

Side by Side Diff: gpu/command_buffer/service/memory_program_cache_unittest.cc

Issue 10534173: GPU Program Caching (Closed) Base URL: http://git.chromium.org/chromium/src.git@master
Patch Set: tiny fix for android and windows build Created 8 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
(Empty)
1 // Copyright (c) 2012 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/service/memory_program_cache.h"
6
7 #include "gpu/command_buffer/common/gl_mock.h"
8 #include "gpu/command_buffer/common/gles2_cmd_format.h"
9 #include "gpu/command_buffer/service/gl_utils.h"
10 #include "gpu/command_buffer/service/shader_translator.h"
11 #include "testing/gtest/include/gtest/gtest.h"
12 #include "ui/gl/gl_bindings.h"
13
14 using ::testing::_;
15 using ::testing::ElementsAreArray;
16 using ::testing::Invoke;
17 using ::testing::SetArgPointee;
18 using ::testing::SetArrayArgument;
19
20 namespace gpu {
21 namespace gles2 {
22
23 class ProgramBinaryEmulator {
24 public:
25 ProgramBinaryEmulator(GLsizei length,
26 GLenum format,
27 const char* binary)
28 : length_(length),
29 format_(format),
30 binary_(binary) { }
31
32 void GetProgramBinary(GLuint program,
33 GLsizei buffer_size,
34 GLsizei* length,
35 GLenum* format,
36 GLvoid* binary) {
37 *length = length_;
38 *format = format_;
39 memcpy(binary, binary_, length_);
40 }
41
42 void ProgramBinary(GLuint program,
43 GLenum format,
44 const GLvoid* binary,
45 GLsizei length) {
46 // format and length are verified by matcher
47 const char* char_binary = static_cast<const char*>(binary);
48 for (int i = 0; i < length; i++) {
49 char expected = binary_[i];
50 EXPECT_EQ(expected, char_binary[i]);
51 }
52 }
53
54 GLsizei length() const { return length_; }
55 GLenum format() const { return format_; }
56 const char* binary() const { return binary_; }
57
58 private:
59 GLsizei length_;
60 GLenum format_;
61 const char* binary_;
62 };
63
64 class MemoryProgramCacheTest : public testing::Test {
65 public:
66 static const size_t kCacheSizeBytes = 1024;
67 static const GLuint kVertexShaderClientId = 90;
68 static const GLuint kVertexShaderServiceId = 100;
69 static const GLuint kFragmentShaderClientId = 91;
70 static const GLuint kFragmentShaderServiceId = 100;
71
72 MemoryProgramCacheTest()
73 : cache_(new MemoryProgramCache(kCacheSizeBytes)),
74 vertex_shader_(NULL),
75 fragment_shader_(NULL) { }
76 ~MemoryProgramCacheTest() {
77 shader_manager_.Destroy(false);
78 }
79
80 protected:
81 virtual void SetUp() {
82 gl_.reset(new ::testing::StrictMock<gfx::MockGLInterface>());
83 ::gfx::GLInterface::SetGLInterface(gl_.get());
84
85 vertex_shader_ = shader_manager_.CreateShaderInfo(kVertexShaderClientId,
86 kVertexShaderServiceId,
87 GL_VERTEX_SHADER);
88 fragment_shader_ = shader_manager_.CreateShaderInfo(
89 kFragmentShaderClientId,
90 kFragmentShaderServiceId,
91 GL_FRAGMENT_SHADER);
92 ASSERT_TRUE(vertex_shader_ != NULL);
93 ASSERT_TRUE(fragment_shader_ != NULL);
94 typedef ShaderTranslatorInterface::VariableInfo VariableInfo;
95 typedef ShaderTranslator::VariableMap VariableMap;
96 VariableMap vertex_attrib_map;
97 VariableMap vertex_uniform_map;
98 VariableMap fragment_attrib_map;
99 VariableMap fragment_uniform_map;
100
101 vertex_attrib_map["a"] = VariableInfo(1, 34, "a");
102 vertex_uniform_map["a"] = VariableInfo(0, 10, "a");
103 vertex_uniform_map["b"] = VariableInfo(2, 3114, "b");
104 fragment_attrib_map["jjjbb"] = VariableInfo(463, 1114, "jjjbb");
105 fragment_uniform_map["k"] = VariableInfo(10, 34413, "k");
106
107 vertex_shader_->set_attrib_map(vertex_attrib_map);
108 vertex_shader_->set_uniform_map(vertex_uniform_map);
109 fragment_shader_->set_attrib_map(vertex_attrib_map);
110 fragment_shader_->set_uniform_map(vertex_uniform_map);
111
112 vertex_shader_->UpdateSource("bbbalsldkdkdkd");
113 fragment_shader_->UpdateSource("bbbal sldkdkdkas 134 ad");
114
115 vertex_shader_->SetStatus(true, NULL, NULL);
116 fragment_shader_->SetStatus(true, NULL, NULL);
117 }
118
119 virtual void TearDown() {
120 ::gfx::GLInterface::SetGLInterface(NULL);
121 gl_.reset();
122 }
123
124 void SetExpectationsForSaveLinkedProgram(
125 const GLint program_id,
126 ProgramBinaryEmulator* emulator) const {
127 EXPECT_CALL(*gl_.get(),
128 GetProgramiv(program_id, GL_PROGRAM_BINARY_LENGTH_OES, _))
129 .WillOnce(SetArgPointee<2>(emulator->length()));
130 EXPECT_CALL(*gl_.get(),
131 GetProgramBinary(program_id, emulator->length(), _, _, _))
132 .WillOnce(Invoke(emulator, &ProgramBinaryEmulator::GetProgramBinary));
133 }
134
135 void SetExpectationsForLoadLinkedProgram(
136 const GLint program_id,
137 ProgramBinaryEmulator* emulator) const {
138 EXPECT_CALL(*gl_.get(),
139 ProgramBinary(program_id,
140 emulator->format(),
141 _,
142 emulator->length()))
143 .WillOnce(Invoke(emulator, &ProgramBinaryEmulator::ProgramBinary));
144 }
145
146 // Use StrictMock to make 100% sure we know how GL will be called.
147 scoped_ptr< ::testing::StrictMock<gfx::MockGLInterface> > gl_;
148 scoped_ptr<MemoryProgramCache> cache_;
149 ShaderManager shader_manager_;
150 ShaderManager::ShaderInfo* vertex_shader_;
151 ShaderManager::ShaderInfo* fragment_shader_;
152 };
153
154 TEST_F(MemoryProgramCacheTest, CacheSave) {
155 const GLenum kFormat = 1;
156 const int kProgramId = 10;
157 const int kBinaryLength = 20;
158 char testBinary[kBinaryLength];
159 for (int i = 0; i < kBinaryLength; ++i) {
160 testBinary[i] = i;
161 }
162 ProgramBinaryEmulator emulator(kBinaryLength, kFormat, testBinary);
163
164 SetExpectationsForSaveLinkedProgram(kProgramId, &emulator);
165 cache_->SaveLinkedProgram(kProgramId, vertex_shader_, fragment_shader_, NULL);
166
167 EXPECT_EQ(ProgramCache::LINK_SUCCEEDED, cache_->GetLinkedProgramStatus(
168 *vertex_shader_->source(),
169 *fragment_shader_->source(),
170 NULL));
171 }
172
173 TEST_F(MemoryProgramCacheTest, CacheLoadMatchesSave) {
174 typedef ShaderTranslator::VariableMap VariableMap;
175 const GLenum kFormat = 1;
176 const int kProgramId = 10;
177 const int kBinaryLength = 20;
178 char testBinary[kBinaryLength];
179 for (int i = 0; i < kBinaryLength; ++i) {
180 testBinary[i] = i;
181 }
182 ProgramBinaryEmulator emulator(kBinaryLength, kFormat, testBinary);
183
184 SetExpectationsForSaveLinkedProgram(kProgramId, &emulator);
185 cache_->SaveLinkedProgram(kProgramId, vertex_shader_, fragment_shader_, NULL);
186
187 VariableMap vertex_attrib_map = vertex_shader_->attrib_map();
188 VariableMap vertex_uniform_map = vertex_shader_->uniform_map();
189 VariableMap fragment_attrib_map = fragment_shader_->attrib_map();
190 VariableMap fragment_uniform_map = fragment_shader_->uniform_map();
191
192 vertex_shader_->set_attrib_map(VariableMap());
193 vertex_shader_->set_uniform_map(VariableMap());
194 fragment_shader_->set_attrib_map(VariableMap());
195 fragment_shader_->set_uniform_map(VariableMap());
196
197 SetExpectationsForLoadLinkedProgram(kProgramId, &emulator);
198
199 EXPECT_EQ(ProgramCache::PROGRAM_LOAD_SUCCESS, cache_->LoadLinkedProgram(
200 kProgramId,
201 vertex_shader_,
202 fragment_shader_,
203 NULL));
204
205 // apparently the hash_map implementation on android doesn't have the
206 // equality operator
207 #if !defined(OS_ANDROID)
208 EXPECT_EQ(vertex_attrib_map, vertex_shader_->attrib_map());
209 EXPECT_EQ(vertex_attrib_map, vertex_shader_->uniform_map());
210 EXPECT_EQ(vertex_attrib_map, fragment_shader_->attrib_map());
211 EXPECT_EQ(vertex_attrib_map, fragment_shader_->uniform_map());
212 #endif
213 }
214
215 TEST_F(MemoryProgramCacheTest, LoadFailOnDifferentSource) {
216 typedef ShaderTranslator::VariableMap VariableMap;
217 const GLenum kFormat = 1;
218 const int kProgramId = 10;
219 const int kBinaryLength = 20;
220 char testBinary[kBinaryLength];
221 for (int i = 0; i < kBinaryLength; ++i) {
222 testBinary[i] = i;
223 }
224 ProgramBinaryEmulator emulator(kBinaryLength, kFormat, testBinary);
225
226 SetExpectationsForSaveLinkedProgram(kProgramId, &emulator);
227 cache_->SaveLinkedProgram(kProgramId, vertex_shader_, fragment_shader_, NULL);
228
229 const std::string vertex_orig_source = *vertex_shader_->source();
230 vertex_shader_->UpdateSource("different!");
231 EXPECT_EQ(ProgramCache::PROGRAM_LOAD_FAILURE, cache_->LoadLinkedProgram(
232 kProgramId,
233 vertex_shader_,
234 fragment_shader_,
235 NULL));
236
237 vertex_shader_->UpdateSource(vertex_orig_source.c_str());
238 fragment_shader_->UpdateSource("different!");
239 EXPECT_EQ(ProgramCache::PROGRAM_LOAD_FAILURE, cache_->LoadLinkedProgram(
240 kProgramId,
241 vertex_shader_,
242 fragment_shader_,
243 NULL));
244 }
245
246 TEST_F(MemoryProgramCacheTest, LoadFailOnDifferentMap) {
247 typedef ShaderTranslator::VariableMap VariableMap;
248 const GLenum kFormat = 1;
249 const int kProgramId = 10;
250 const int kBinaryLength = 20;
251 char testBinary[kBinaryLength];
252 for (int i = 0; i < kBinaryLength; ++i) {
253 testBinary[i] = i;
254 }
255 ProgramBinaryEmulator emulator(kBinaryLength, kFormat, testBinary);
256
257 SetExpectationsForSaveLinkedProgram(kProgramId, &emulator);
258 ProgramCache::LocationMap binding_map;
259 binding_map["test"] = 512;
260 cache_->SaveLinkedProgram(kProgramId,
261 vertex_shader_,
262 fragment_shader_,
263 &binding_map);
264
265 binding_map["different!"] = 59;
266 EXPECT_EQ(ProgramCache::PROGRAM_LOAD_FAILURE, cache_->LoadLinkedProgram(
267 kProgramId,
268 vertex_shader_,
269 fragment_shader_,
270 &binding_map));
271 EXPECT_EQ(ProgramCache::PROGRAM_LOAD_FAILURE, cache_->LoadLinkedProgram(
272 kProgramId,
273 vertex_shader_,
274 fragment_shader_,
275 NULL));
276 }
277
278 TEST_F(MemoryProgramCacheTest, MemoryProgramCacheEviction) {
279 typedef ShaderTranslator::VariableMap VariableMap;
280 const GLenum kFormat = 1;
281 const int kProgramId = 10;
282 const int kBinaryLength = 20;
283 char testBinary[kBinaryLength];
284 for (int i = 0; i < kBinaryLength; ++i) {
285 testBinary[i] = i;
286 }
287 ProgramBinaryEmulator emulator1(kBinaryLength, kFormat, testBinary);
288
289
290 SetExpectationsForSaveLinkedProgram(kProgramId, &emulator1);
291 cache_->SaveLinkedProgram(kProgramId, vertex_shader_, fragment_shader_, NULL);
292
293 const int kEvictingProgramId = 11;
294 const GLuint kEvictingBinaryLength = kCacheSizeBytes - kBinaryLength + 1;
295
296 // save old source and modify for new program
297 const std::string old_source(*fragment_shader_->source());
298 fragment_shader_->UpdateSource("al sdfkjdk");
299
300 scoped_array<char> bigTestBinary =
301 scoped_array<char>(new char[kEvictingBinaryLength]);
302 for (size_t i = 0; i < kEvictingBinaryLength; ++i) {
303 bigTestBinary[i] = i % 250;
304 }
305 ProgramBinaryEmulator emulator2(kEvictingBinaryLength,
306 kFormat,
307 bigTestBinary.get());
308
309 SetExpectationsForSaveLinkedProgram(kEvictingProgramId, &emulator2);
310 cache_->SaveLinkedProgram(kEvictingProgramId,
311 vertex_shader_,
312 fragment_shader_,
313 NULL);
314
315 EXPECT_EQ(ProgramCache::LINK_SUCCEEDED, cache_->GetLinkedProgramStatus(
316 *vertex_shader_->source(),
317 *fragment_shader_->source(),
318 NULL));
319 EXPECT_EQ(ProgramCache::LINK_UNKNOWN, cache_->GetLinkedProgramStatus(
320 old_source,
321 *fragment_shader_->source(),
322 NULL));
323 }
324
325 } // namespace gles2
326 } // namespace gpu
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698