- add sources.
[platform/framework/web/crosswalk.git] / src / gpu / command_buffer / service / memory_program_cache_unittest.cc
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 "base/bind.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_manager.h"
11 #include "gpu/command_buffer/service/shader_translator.h"
12 #include "testing/gtest/include/gtest/gtest.h"
13 #include "ui/gl/gl_bindings.h"
14 #include "ui/gl/gl_mock.h"
15
16 using ::testing::_;
17 using ::testing::ElementsAreArray;
18 using ::testing::Invoke;
19 using ::testing::SetArgPointee;
20 using ::testing::SetArrayArgument;
21
22 namespace {
23 typedef gpu::gles2::ShaderTranslator::VariableMap VariableMap;
24 }  // anonymous namespace
25
26 namespace gpu {
27 namespace gles2 {
28
29 class ProgramBinaryEmulator {
30  public:
31   ProgramBinaryEmulator(GLsizei length,
32                         GLenum format,
33                         const char* binary)
34       : length_(length),
35         format_(format),
36         binary_(binary) { }
37
38   void GetProgramBinary(GLuint program,
39                         GLsizei buffer_size,
40                         GLsizei* length,
41                         GLenum* format,
42                         GLvoid* binary) {
43     if (length) {
44       *length = length_;
45     }
46     *format = format_;
47     memcpy(binary, binary_, length_);
48   }
49
50   void ProgramBinary(GLuint program,
51                      GLenum format,
52                      const GLvoid* binary,
53                      GLsizei length) {
54     // format and length are verified by matcher
55     EXPECT_EQ(0, memcmp(binary_, binary, length));
56   }
57
58   GLsizei length() const { return length_; }
59   GLenum format() const { return format_; }
60   const char* binary() const { return binary_; }
61
62  private:
63   GLsizei length_;
64   GLenum format_;
65   const char* binary_;
66 };
67
68 class MemoryProgramCacheTest : public testing::Test {
69  public:
70   static const size_t kCacheSizeBytes = 1024;
71   static const GLuint kVertexShaderClientId = 90;
72   static const GLuint kVertexShaderServiceId = 100;
73   static const GLuint kFragmentShaderClientId = 91;
74   static const GLuint kFragmentShaderServiceId = 100;
75
76   MemoryProgramCacheTest()
77       : cache_(new MemoryProgramCache(kCacheSizeBytes)),
78         vertex_shader_(NULL),
79         fragment_shader_(NULL),
80         shader_cache_count_(0) { }
81   virtual ~MemoryProgramCacheTest() {
82     shader_manager_.Destroy(false);
83   }
84
85   void ShaderCacheCb(const std::string& key, const std::string& shader) {
86     shader_cache_count_++;
87     shader_cache_shader_ = shader;
88   }
89
90   int32 shader_cache_count() { return shader_cache_count_; }
91   const std::string& shader_cache_shader() { return shader_cache_shader_; }
92
93  protected:
94   virtual void SetUp() {
95     gl_.reset(new ::testing::StrictMock<gfx::MockGLInterface>());
96     ::gfx::GLInterface::SetGLInterface(gl_.get());
97
98     vertex_shader_ = shader_manager_.CreateShader(kVertexShaderClientId,
99                                                   kVertexShaderServiceId,
100                                                   GL_VERTEX_SHADER);
101     fragment_shader_ = shader_manager_.CreateShader(
102         kFragmentShaderClientId,
103         kFragmentShaderServiceId,
104         GL_FRAGMENT_SHADER);
105     ASSERT_TRUE(vertex_shader_ != NULL);
106     ASSERT_TRUE(fragment_shader_ != NULL);
107     typedef ShaderTranslatorInterface::VariableInfo VariableInfo;
108     typedef ShaderTranslator::VariableMap VariableMap;
109     VariableMap vertex_attrib_map;
110     VariableMap vertex_uniform_map;
111     VariableMap vertex_varying_map;
112     VariableMap fragment_attrib_map;
113     VariableMap fragment_uniform_map;
114     VariableMap fragment_varying_map;
115
116     vertex_attrib_map["a"] = VariableInfo(1, 34, SH_PRECISION_LOWP, 0, "a");
117     vertex_uniform_map["a"] = VariableInfo(0, 10, SH_PRECISION_MEDIUMP, 1, "a");
118     vertex_uniform_map["b"] = VariableInfo(2, 3114, SH_PRECISION_HIGHP, 1, "b");
119     vertex_varying_map["c"] = VariableInfo(3, 2, SH_PRECISION_HIGHP, 1, "c");
120     fragment_attrib_map["jjjbb"] =
121         VariableInfo(463, 1114, SH_PRECISION_MEDIUMP, 0, "jjjbb");
122     fragment_uniform_map["k"] =
123         VariableInfo(10, 34413, SH_PRECISION_MEDIUMP, 1, "k");
124     fragment_varying_map["c"] = VariableInfo(3, 2, SH_PRECISION_HIGHP, 1, "c");
125
126     vertex_shader_->set_attrib_map(vertex_attrib_map);
127     vertex_shader_->set_uniform_map(vertex_uniform_map);
128     vertex_shader_->set_varying_map(vertex_varying_map);
129     fragment_shader_->set_attrib_map(vertex_attrib_map);
130     fragment_shader_->set_uniform_map(vertex_uniform_map);
131     fragment_shader_->set_varying_map(vertex_varying_map);
132
133     vertex_shader_->UpdateSource("bbbalsldkdkdkd");
134     fragment_shader_->UpdateSource("bbbal   sldkdkdkas 134 ad");
135
136     vertex_shader_->SetStatus(true, NULL, NULL);
137     fragment_shader_->SetStatus(true, NULL, NULL);
138   }
139
140   virtual void TearDown() {
141     ::gfx::GLInterface::SetGLInterface(NULL);
142     gl_.reset();
143   }
144
145   void SetExpectationsForSaveLinkedProgram(
146       const GLint program_id,
147       ProgramBinaryEmulator* emulator) const {
148     EXPECT_CALL(*gl_.get(),
149                 GetProgramiv(program_id, GL_PROGRAM_BINARY_LENGTH_OES, _))
150         .WillOnce(SetArgPointee<2>(emulator->length()));
151     EXPECT_CALL(*gl_.get(),
152                 GetProgramBinary(program_id, emulator->length(), _, _, _))
153         .WillOnce(Invoke(emulator, &ProgramBinaryEmulator::GetProgramBinary));
154   }
155
156   void SetExpectationsForLoadLinkedProgram(
157       const GLint program_id,
158       ProgramBinaryEmulator* emulator) const {
159     EXPECT_CALL(*gl_.get(),
160                 ProgramBinary(program_id,
161                               emulator->format(),
162                               _,
163                               emulator->length()))
164         .WillOnce(Invoke(emulator, &ProgramBinaryEmulator::ProgramBinary));
165     EXPECT_CALL(*gl_.get(),
166                 GetProgramiv(program_id, GL_LINK_STATUS, _))
167                 .WillOnce(SetArgPointee<2>(GL_TRUE));
168   }
169
170   void SetExpectationsForLoadLinkedProgramFailure(
171       const GLint program_id,
172       ProgramBinaryEmulator* emulator) const {
173     EXPECT_CALL(*gl_.get(),
174                 ProgramBinary(program_id,
175                               emulator->format(),
176                               _,
177                               emulator->length()))
178         .WillOnce(Invoke(emulator, &ProgramBinaryEmulator::ProgramBinary));
179     EXPECT_CALL(*gl_.get(),
180                 GetProgramiv(program_id, GL_LINK_STATUS, _))
181                 .WillOnce(SetArgPointee<2>(GL_FALSE));
182   }
183
184   // Use StrictMock to make 100% sure we know how GL will be called.
185   scoped_ptr< ::testing::StrictMock<gfx::MockGLInterface> > gl_;
186   scoped_ptr<MemoryProgramCache> cache_;
187   ShaderManager shader_manager_;
188   Shader* vertex_shader_;
189   Shader* fragment_shader_;
190   int32 shader_cache_count_;
191   std::string shader_cache_shader_;
192 };
193
194 TEST_F(MemoryProgramCacheTest, CacheSave) {
195   const GLenum kFormat = 1;
196   const int kProgramId = 10;
197   const int kBinaryLength = 20;
198   char test_binary[kBinaryLength];
199   for (int i = 0; i < kBinaryLength; ++i) {
200     test_binary[i] = i;
201   }
202   ProgramBinaryEmulator emulator(kBinaryLength, kFormat, test_binary);
203
204   SetExpectationsForSaveLinkedProgram(kProgramId, &emulator);
205   cache_->SaveLinkedProgram(kProgramId, vertex_shader_, NULL,
206                             fragment_shader_, NULL, NULL,
207                             base::Bind(&MemoryProgramCacheTest::ShaderCacheCb,
208                                        base::Unretained(this)));
209
210   EXPECT_EQ(ProgramCache::LINK_SUCCEEDED, cache_->GetLinkedProgramStatus(
211       *vertex_shader_->signature_source(),
212       NULL,
213       *fragment_shader_->signature_source(),
214       NULL,
215       NULL));
216   EXPECT_EQ(1, shader_cache_count());
217 }
218
219 TEST_F(MemoryProgramCacheTest, LoadProgram) {
220   const GLenum kFormat = 1;
221   const int kProgramId = 10;
222   const int kBinaryLength = 20;
223   char test_binary[kBinaryLength];
224   for (int i = 0; i < kBinaryLength; ++i) {
225     test_binary[i] = i;
226   }
227   ProgramBinaryEmulator emulator(kBinaryLength, kFormat, test_binary);
228
229   SetExpectationsForSaveLinkedProgram(kProgramId, &emulator);
230   cache_->SaveLinkedProgram(kProgramId, vertex_shader_, NULL,
231                             fragment_shader_, NULL, NULL,
232                             base::Bind(&MemoryProgramCacheTest::ShaderCacheCb,
233                                        base::Unretained(this)));
234
235   EXPECT_EQ(ProgramCache::LINK_SUCCEEDED, cache_->GetLinkedProgramStatus(
236       *vertex_shader_->signature_source(),
237       NULL,
238       *fragment_shader_->signature_source(),
239       NULL,
240       NULL));
241   EXPECT_EQ(1, shader_cache_count());
242
243   cache_->Clear();
244
245   cache_->LoadProgram(shader_cache_shader());
246   EXPECT_EQ(ProgramCache::LINK_SUCCEEDED, cache_->GetLinkedProgramStatus(
247       *vertex_shader_->signature_source(),
248       NULL,
249       *fragment_shader_->signature_source(),
250       NULL,
251       NULL));
252 }
253
254 TEST_F(MemoryProgramCacheTest, CacheLoadMatchesSave) {
255   const GLenum kFormat = 1;
256   const int kProgramId = 10;
257   const int kBinaryLength = 20;
258   char test_binary[kBinaryLength];
259   for (int i = 0; i < kBinaryLength; ++i) {
260     test_binary[i] = i;
261   }
262   ProgramBinaryEmulator emulator(kBinaryLength, kFormat, test_binary);
263
264   SetExpectationsForSaveLinkedProgram(kProgramId, &emulator);
265   cache_->SaveLinkedProgram(kProgramId, vertex_shader_, NULL,
266                             fragment_shader_, NULL, NULL,
267                             base::Bind(&MemoryProgramCacheTest::ShaderCacheCb,
268                                        base::Unretained(this)));
269   EXPECT_EQ(1, shader_cache_count());
270
271   VariableMap vertex_attrib_map = vertex_shader_->attrib_map();
272   VariableMap vertex_uniform_map = vertex_shader_->uniform_map();
273   VariableMap vertex_varying_map = vertex_shader_->varying_map();
274   VariableMap fragment_attrib_map = fragment_shader_->attrib_map();
275   VariableMap fragment_uniform_map = fragment_shader_->uniform_map();
276   VariableMap fragment_varying_map = fragment_shader_->varying_map();
277
278   vertex_shader_->set_attrib_map(VariableMap());
279   vertex_shader_->set_uniform_map(VariableMap());
280   vertex_shader_->set_varying_map(VariableMap());
281   fragment_shader_->set_attrib_map(VariableMap());
282   fragment_shader_->set_uniform_map(VariableMap());
283   fragment_shader_->set_varying_map(VariableMap());
284
285   SetExpectationsForLoadLinkedProgram(kProgramId, &emulator);
286
287   EXPECT_EQ(ProgramCache::PROGRAM_LOAD_SUCCESS, cache_->LoadLinkedProgram(
288       kProgramId,
289       vertex_shader_,
290       NULL,
291       fragment_shader_,
292       NULL,
293       NULL,
294       base::Bind(&MemoryProgramCacheTest::ShaderCacheCb,
295                  base::Unretained(this))));
296
297   // apparently the hash_map implementation on android doesn't have the
298   // equality operator
299 #if !defined(OS_ANDROID)
300   EXPECT_EQ(vertex_attrib_map, vertex_shader_->attrib_map());
301   EXPECT_EQ(vertex_uniform_map, vertex_shader_->uniform_map());
302   EXPECT_EQ(vertex_varying_map, vertex_shader_->varying_map());
303   EXPECT_EQ(fragment_attrib_map, fragment_shader_->attrib_map());
304   EXPECT_EQ(fragment_uniform_map, fragment_shader_->uniform_map());
305   EXPECT_EQ(fragment_varying_map, fragment_shader_->varying_map());
306 #endif
307 }
308
309 TEST_F(MemoryProgramCacheTest, LoadProgramMatchesSave) {
310   const GLenum kFormat = 1;
311   const int kProgramId = 10;
312   const int kBinaryLength = 20;
313   char test_binary[kBinaryLength];
314   for (int i = 0; i < kBinaryLength; ++i) {
315     test_binary[i] = i;
316   }
317   ProgramBinaryEmulator emulator(kBinaryLength, kFormat, test_binary);
318
319   SetExpectationsForSaveLinkedProgram(kProgramId, &emulator);
320   cache_->SaveLinkedProgram(kProgramId, vertex_shader_, NULL,
321                             fragment_shader_, NULL, NULL,
322                             base::Bind(&MemoryProgramCacheTest::ShaderCacheCb,
323                                        base::Unretained(this)));
324   EXPECT_EQ(1, shader_cache_count());
325
326   VariableMap vertex_attrib_map = vertex_shader_->attrib_map();
327   VariableMap vertex_uniform_map = vertex_shader_->uniform_map();
328   VariableMap vertex_varying_map = vertex_shader_->varying_map();
329   VariableMap fragment_attrib_map = fragment_shader_->attrib_map();
330   VariableMap fragment_uniform_map = fragment_shader_->uniform_map();
331   VariableMap fragment_varying_map = fragment_shader_->varying_map();
332
333   vertex_shader_->set_attrib_map(VariableMap());
334   vertex_shader_->set_uniform_map(VariableMap());
335   vertex_shader_->set_varying_map(VariableMap());
336   fragment_shader_->set_attrib_map(VariableMap());
337   fragment_shader_->set_uniform_map(VariableMap());
338   fragment_shader_->set_varying_map(VariableMap());
339
340   SetExpectationsForLoadLinkedProgram(kProgramId, &emulator);
341
342   cache_->Clear();
343   cache_->LoadProgram(shader_cache_shader());
344
345   EXPECT_EQ(ProgramCache::PROGRAM_LOAD_SUCCESS, cache_->LoadLinkedProgram(
346       kProgramId,
347       vertex_shader_,
348       NULL,
349       fragment_shader_,
350       NULL,
351       NULL,
352       base::Bind(&MemoryProgramCacheTest::ShaderCacheCb,
353                  base::Unretained(this))));
354
355   // apparently the hash_map implementation on android doesn't have the
356   // equality operator
357 #if !defined(OS_ANDROID)
358   EXPECT_EQ(vertex_attrib_map, vertex_shader_->attrib_map());
359   EXPECT_EQ(vertex_uniform_map, vertex_shader_->uniform_map());
360   EXPECT_EQ(vertex_varying_map, vertex_shader_->varying_map());
361   EXPECT_EQ(fragment_attrib_map, fragment_shader_->attrib_map());
362   EXPECT_EQ(fragment_uniform_map, fragment_shader_->uniform_map());
363   EXPECT_EQ(fragment_varying_map, fragment_shader_->varying_map());
364 #endif
365 }
366
367 TEST_F(MemoryProgramCacheTest, LoadFailOnLinkFalse) {
368   const GLenum kFormat = 1;
369   const int kProgramId = 10;
370   const int kBinaryLength = 20;
371   char test_binary[kBinaryLength];
372   for (int i = 0; i < kBinaryLength; ++i) {
373     test_binary[i] = i;
374   }
375   ProgramBinaryEmulator emulator(kBinaryLength, kFormat, test_binary);
376
377   SetExpectationsForSaveLinkedProgram(kProgramId, &emulator);
378   cache_->SaveLinkedProgram(kProgramId, vertex_shader_, NULL,
379                             fragment_shader_, NULL, NULL,
380                             base::Bind(&MemoryProgramCacheTest::ShaderCacheCb,
381                                        base::Unretained(this)));
382
383   SetExpectationsForLoadLinkedProgramFailure(kProgramId, &emulator);
384   EXPECT_EQ(ProgramCache::PROGRAM_LOAD_FAILURE, cache_->LoadLinkedProgram(
385       kProgramId,
386       vertex_shader_,
387       NULL,
388       fragment_shader_,
389       NULL,
390       NULL,
391       base::Bind(&MemoryProgramCacheTest::ShaderCacheCb,
392                  base::Unretained(this))));
393 }
394
395 TEST_F(MemoryProgramCacheTest, LoadFailOnDifferentSource) {
396   const GLenum kFormat = 1;
397   const int kProgramId = 10;
398   const int kBinaryLength = 20;
399   char test_binary[kBinaryLength];
400   for (int i = 0; i < kBinaryLength; ++i) {
401     test_binary[i] = i;
402   }
403   ProgramBinaryEmulator emulator(kBinaryLength, kFormat, test_binary);
404
405   SetExpectationsForSaveLinkedProgram(kProgramId, &emulator);
406   cache_->SaveLinkedProgram(kProgramId, vertex_shader_, NULL,
407                             fragment_shader_, NULL, NULL,
408                             base::Bind(&MemoryProgramCacheTest::ShaderCacheCb,
409                                        base::Unretained(this)));
410
411   const std::string vertex_orig_source =
412       *vertex_shader_->signature_source();
413   vertex_shader_->UpdateSource("different!");
414   vertex_shader_->SetStatus(true, NULL, NULL);
415   EXPECT_EQ(ProgramCache::PROGRAM_LOAD_FAILURE, cache_->LoadLinkedProgram(
416       kProgramId,
417       vertex_shader_,
418       NULL,
419       fragment_shader_,
420       NULL,
421       NULL,
422       base::Bind(&MemoryProgramCacheTest::ShaderCacheCb,
423                  base::Unretained(this))));
424
425   vertex_shader_->UpdateSource(vertex_orig_source.c_str());
426   vertex_shader_->SetStatus(true, NULL, NULL);
427   fragment_shader_->UpdateSource("different!");
428   fragment_shader_->SetStatus(true, NULL, NULL);
429   EXPECT_EQ(ProgramCache::PROGRAM_LOAD_FAILURE, cache_->LoadLinkedProgram(
430       kProgramId,
431       vertex_shader_,
432       NULL,
433       fragment_shader_,
434       NULL,
435       NULL,
436       base::Bind(&MemoryProgramCacheTest::ShaderCacheCb,
437                  base::Unretained(this))));
438 }
439
440 TEST_F(MemoryProgramCacheTest, LoadFailOnDifferentMap) {
441   const GLenum kFormat = 1;
442   const int kProgramId = 10;
443   const int kBinaryLength = 20;
444   char test_binary[kBinaryLength];
445   for (int i = 0; i < kBinaryLength; ++i) {
446     test_binary[i] = i;
447   }
448   ProgramBinaryEmulator emulator(kBinaryLength, kFormat, test_binary);
449
450   SetExpectationsForSaveLinkedProgram(kProgramId, &emulator);
451   ProgramCache::LocationMap binding_map;
452   binding_map["test"] = 512;
453   cache_->SaveLinkedProgram(kProgramId,
454                             vertex_shader_,
455                             NULL,
456                             fragment_shader_,
457                             NULL,
458                             &binding_map,
459                             base::Bind(&MemoryProgramCacheTest::ShaderCacheCb,
460                                        base::Unretained(this)));
461
462   binding_map["different!"] = 59;
463   EXPECT_EQ(ProgramCache::PROGRAM_LOAD_FAILURE, cache_->LoadLinkedProgram(
464       kProgramId,
465       vertex_shader_,
466       NULL,
467       fragment_shader_,
468       NULL,
469       &binding_map,
470       base::Bind(&MemoryProgramCacheTest::ShaderCacheCb,
471                  base::Unretained(this))));
472   EXPECT_EQ(ProgramCache::PROGRAM_LOAD_FAILURE, cache_->LoadLinkedProgram(
473       kProgramId,
474       vertex_shader_,
475       NULL,
476       fragment_shader_,
477       NULL,
478       NULL,
479       base::Bind(&MemoryProgramCacheTest::ShaderCacheCb,
480                  base::Unretained(this))));
481 }
482
483 TEST_F(MemoryProgramCacheTest, MemoryProgramCacheEviction) {
484   typedef ShaderTranslator::VariableMap VariableMap;
485   const GLenum kFormat = 1;
486   const int kProgramId = 10;
487   const int kBinaryLength = 20;
488   char test_binary[kBinaryLength];
489   for (int i = 0; i < kBinaryLength; ++i) {
490     test_binary[i] = i;
491   }
492   ProgramBinaryEmulator emulator1(kBinaryLength, kFormat, test_binary);
493
494
495   SetExpectationsForSaveLinkedProgram(kProgramId, &emulator1);
496   cache_->SaveLinkedProgram(kProgramId, vertex_shader_, NULL,
497                             fragment_shader_, NULL, NULL,
498                             base::Bind(&MemoryProgramCacheTest::ShaderCacheCb,
499                                        base::Unretained(this)));
500
501   const int kEvictingProgramId = 11;
502   const GLuint kEvictingBinaryLength = kCacheSizeBytes - kBinaryLength + 1;
503
504   // save old source and modify for new program
505   const std::string old_source =
506       *fragment_shader_->signature_source();
507   fragment_shader_->UpdateSource("al sdfkjdk");
508   fragment_shader_->SetStatus(true, NULL, NULL);
509
510   scoped_ptr<char[]> bigTestBinary =
511       scoped_ptr<char[]>(new char[kEvictingBinaryLength]);
512   for (size_t i = 0; i < kEvictingBinaryLength; ++i) {
513     bigTestBinary[i] = i % 250;
514   }
515   ProgramBinaryEmulator emulator2(kEvictingBinaryLength,
516                                   kFormat,
517                                   bigTestBinary.get());
518
519   SetExpectationsForSaveLinkedProgram(kEvictingProgramId, &emulator2);
520   cache_->SaveLinkedProgram(kEvictingProgramId,
521                             vertex_shader_,
522                             NULL,
523                             fragment_shader_,
524                             NULL,
525                             NULL,
526                             base::Bind(&MemoryProgramCacheTest::ShaderCacheCb,
527                                        base::Unretained(this)));
528
529   EXPECT_EQ(ProgramCache::LINK_SUCCEEDED, cache_->GetLinkedProgramStatus(
530       *vertex_shader_->signature_source(),
531       NULL,
532       *fragment_shader_->signature_source(),
533       NULL,
534       NULL));
535   EXPECT_EQ(ProgramCache::LINK_UNKNOWN, cache_->GetLinkedProgramStatus(
536       old_source,
537       NULL,
538       *fragment_shader_->signature_source(),
539       NULL,
540       NULL));
541 }
542
543 TEST_F(MemoryProgramCacheTest, SaveCorrectProgram) {
544   const GLenum kFormat = 1;
545   const int kProgramId = 10;
546   const int kBinaryLength = 20;
547   char test_binary[kBinaryLength];
548   for (int i = 0; i < kBinaryLength; ++i) {
549     test_binary[i] = i;
550   }
551   ProgramBinaryEmulator emulator1(kBinaryLength, kFormat, test_binary);
552
553   vertex_shader_->UpdateSource("different!");
554   SetExpectationsForSaveLinkedProgram(kProgramId, &emulator1);
555   cache_->SaveLinkedProgram(kProgramId, vertex_shader_, NULL,
556                             fragment_shader_, NULL, NULL,
557                             base::Bind(&MemoryProgramCacheTest::ShaderCacheCb,
558                                        base::Unretained(this)));
559
560   EXPECT_EQ(ProgramCache::LINK_SUCCEEDED, cache_->GetLinkedProgramStatus(
561       *vertex_shader_->signature_source(),
562       NULL,
563       *fragment_shader_->signature_source(),
564       NULL,
565       NULL));
566 }
567
568 TEST_F(MemoryProgramCacheTest, LoadCorrectProgram) {
569   const GLenum kFormat = 1;
570   const int kProgramId = 10;
571   const int kBinaryLength = 20;
572   char test_binary[kBinaryLength];
573   for (int i = 0; i < kBinaryLength; ++i) {
574     test_binary[i] = i;
575   }
576   ProgramBinaryEmulator emulator(kBinaryLength, kFormat, test_binary);
577
578   SetExpectationsForSaveLinkedProgram(kProgramId, &emulator);
579   cache_->SaveLinkedProgram(kProgramId, vertex_shader_, NULL,
580                             fragment_shader_, NULL, NULL,
581                             base::Bind(&MemoryProgramCacheTest::ShaderCacheCb,
582                                        base::Unretained(this)));
583
584   EXPECT_EQ(ProgramCache::LINK_SUCCEEDED, cache_->GetLinkedProgramStatus(
585       *vertex_shader_->signature_source(),
586       NULL,
587       *fragment_shader_->signature_source(),
588       NULL,
589       NULL));
590
591   SetExpectationsForLoadLinkedProgram(kProgramId, &emulator);
592
593   fragment_shader_->UpdateSource("different!");
594   EXPECT_EQ(ProgramCache::PROGRAM_LOAD_SUCCESS, cache_->LoadLinkedProgram(
595       kProgramId,
596       vertex_shader_,
597       NULL,
598       fragment_shader_,
599       NULL,
600       NULL,
601       base::Bind(&MemoryProgramCacheTest::ShaderCacheCb,
602                  base::Unretained(this))));
603 }
604
605 TEST_F(MemoryProgramCacheTest, OverwriteOnNewSave) {
606   const GLenum kFormat = 1;
607   const int kProgramId = 10;
608   const int kBinaryLength = 20;
609   char test_binary[kBinaryLength];
610   for (int i = 0; i < kBinaryLength; ++i) {
611     test_binary[i] = i;
612   }
613   ProgramBinaryEmulator emulator(kBinaryLength, kFormat, test_binary);
614
615   SetExpectationsForSaveLinkedProgram(kProgramId, &emulator);
616   cache_->SaveLinkedProgram(kProgramId, vertex_shader_, NULL,
617                             fragment_shader_, NULL, NULL,
618                             base::Bind(&MemoryProgramCacheTest::ShaderCacheCb,
619                                        base::Unretained(this)));
620
621
622   char test_binary2[kBinaryLength];
623   for (int i = 0; i < kBinaryLength; ++i) {
624     test_binary2[i] = (i*2) % 250;
625   }
626   ProgramBinaryEmulator emulator2(kBinaryLength, kFormat, test_binary2);
627   SetExpectationsForSaveLinkedProgram(kProgramId, &emulator2);
628   cache_->SaveLinkedProgram(kProgramId, vertex_shader_, NULL,
629                             fragment_shader_, NULL, NULL,
630                             base::Bind(&MemoryProgramCacheTest::ShaderCacheCb,
631                                        base::Unretained(this)));
632
633   SetExpectationsForLoadLinkedProgram(kProgramId, &emulator2);
634   EXPECT_EQ(ProgramCache::PROGRAM_LOAD_SUCCESS, cache_->LoadLinkedProgram(
635       kProgramId,
636       vertex_shader_,
637       NULL,
638       fragment_shader_,
639       NULL,
640       NULL,
641       base::Bind(&MemoryProgramCacheTest::ShaderCacheCb,
642                  base::Unretained(this))));
643 }
644
645 }  // namespace gles2
646 }  // namespace gpu