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