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.
5 #include "gpu/command_buffer/service/memory_program_cache.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"
19 using ::testing::Invoke
;
20 using ::testing::SetArgPointee
;
25 class ProgramBinaryEmulator
{
27 ProgramBinaryEmulator(GLsizei length
,
34 void GetProgramBinary(GLuint program
,
43 memcpy(binary
, binary_
, length_
);
46 void ProgramBinary(GLuint program
,
50 // format and length are verified by matcher
51 EXPECT_EQ(0, memcmp(binary_
, binary
, length
));
54 GLsizei
length() const { return length_
; }
55 GLenum
format() const { return format_
; }
56 const char* binary() const { return binary_
; }
64 class MemoryProgramCacheTest
: public GpuServiceTest
{
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;
72 MemoryProgramCacheTest()
73 : cache_(new MemoryProgramCache(kCacheSizeBytes
)),
75 fragment_shader_(NULL
),
76 shader_cache_count_(0) { }
77 ~MemoryProgramCacheTest() override
{ shader_manager_
.Destroy(false); }
79 void ShaderCacheCb(const std::string
& key
, const std::string
& shader
) {
80 shader_cache_count_
++;
81 shader_cache_shader_
= shader
;
84 int32
shader_cache_count() { return shader_cache_count_
; }
85 const std::string
& shader_cache_shader() { return shader_cache_shader_
; }
88 void SetUp() override
{
89 GpuServiceTest::SetUpWithGLVersion("3.0", "GL_ARB_get_program_binary");
91 vertex_shader_
= shader_manager_
.CreateShader(kVertexShaderClientId
,
92 kVertexShaderServiceId
,
94 fragment_shader_
= shader_manager_
.CreateShader(
95 kFragmentShaderClientId
,
96 kFragmentShaderServiceId
,
98 ASSERT_TRUE(vertex_shader_
!= NULL
);
99 ASSERT_TRUE(fragment_shader_
!= NULL
);
100 AttributeMap vertex_attrib_map
;
101 UniformMap vertex_uniform_map
;
102 VaryingMap vertex_varying_map
;
103 AttributeMap fragment_attrib_map
;
104 UniformMap fragment_uniform_map
;
105 VaryingMap fragment_varying_map
;
107 vertex_attrib_map
["a"] = TestHelper::ConstructAttribute(
108 GL_FLOAT_VEC2
, 34, GL_LOW_FLOAT
, false, "a");
109 vertex_uniform_map
["a"] = TestHelper::ConstructUniform(
110 GL_FLOAT
, 10, GL_MEDIUM_FLOAT
, true, "a");
111 vertex_uniform_map
["b"] = TestHelper::ConstructUniform(
112 GL_FLOAT_VEC3
, 3114, GL_HIGH_FLOAT
, true, "b");
113 vertex_varying_map
["c"] = TestHelper::ConstructVarying(
114 GL_FLOAT_VEC4
, 2, GL_HIGH_FLOAT
, true, "c");
115 fragment_attrib_map
["jjjbb"] = TestHelper::ConstructAttribute(
116 GL_FLOAT_MAT4
, 1114, GL_MEDIUM_FLOAT
, false, "jjjbb");
117 fragment_uniform_map
["k"] = TestHelper::ConstructUniform(
118 GL_FLOAT_MAT2
, 34413, GL_MEDIUM_FLOAT
, true, "k");
119 fragment_varying_map
["c"] = TestHelper::ConstructVarying(
120 GL_FLOAT_VEC4
, 2, GL_HIGH_FLOAT
, true, "c");
122 vertex_shader_
->set_source("bbbalsldkdkdkd");
123 fragment_shader_
->set_source("bbbal sldkdkdkas 134 ad");
125 TestHelper::SetShaderStates(
126 gl_
.get(), vertex_shader_
, true, NULL
, NULL
,
127 &vertex_attrib_map
, &vertex_uniform_map
, &vertex_varying_map
,
129 TestHelper::SetShaderStates(
130 gl_
.get(), fragment_shader_
, true, NULL
, NULL
,
131 &fragment_attrib_map
, &fragment_uniform_map
, &fragment_varying_map
,
135 void SetExpectationsForSaveLinkedProgram(
136 const GLint program_id
,
137 ProgramBinaryEmulator
* emulator
) const {
138 EXPECT_CALL(*gl_
.get(),
139 GetProgramiv(program_id
, GL_PROGRAM_BINARY_LENGTH_OES
, _
))
140 .WillOnce(SetArgPointee
<2>(emulator
->length()));
141 EXPECT_CALL(*gl_
.get(),
142 GetProgramBinary(program_id
, emulator
->length(), _
, _
, _
))
143 .WillOnce(Invoke(emulator
, &ProgramBinaryEmulator::GetProgramBinary
));
146 void SetExpectationsForLoadLinkedProgram(
147 const GLint program_id
,
148 ProgramBinaryEmulator
* emulator
) const {
149 EXPECT_CALL(*gl_
.get(),
150 ProgramBinary(program_id
,
154 .WillOnce(Invoke(emulator
, &ProgramBinaryEmulator::ProgramBinary
));
155 EXPECT_CALL(*gl_
.get(),
156 GetProgramiv(program_id
, GL_LINK_STATUS
, _
))
157 .WillOnce(SetArgPointee
<2>(GL_TRUE
));
160 void SetExpectationsForLoadLinkedProgramFailure(
161 const GLint program_id
,
162 ProgramBinaryEmulator
* emulator
) const {
163 EXPECT_CALL(*gl_
.get(),
164 ProgramBinary(program_id
,
168 .WillOnce(Invoke(emulator
, &ProgramBinaryEmulator::ProgramBinary
));
169 EXPECT_CALL(*gl_
.get(),
170 GetProgramiv(program_id
, GL_LINK_STATUS
, _
))
171 .WillOnce(SetArgPointee
<2>(GL_FALSE
));
174 scoped_ptr
<MemoryProgramCache
> cache_
;
175 ShaderManager shader_manager_
;
176 Shader
* vertex_shader_
;
177 Shader
* fragment_shader_
;
178 int32 shader_cache_count_
;
179 std::string shader_cache_shader_
;
180 std::vector
<std::string
> varyings_
;
183 TEST_F(MemoryProgramCacheTest
, CacheSave
) {
184 const GLenum kFormat
= 1;
185 const int kProgramId
= 10;
186 const int kBinaryLength
= 20;
187 char test_binary
[kBinaryLength
];
188 for (int i
= 0; i
< kBinaryLength
; ++i
) {
191 ProgramBinaryEmulator
emulator(kBinaryLength
, kFormat
, test_binary
);
193 SetExpectationsForSaveLinkedProgram(kProgramId
, &emulator
);
194 cache_
->SaveLinkedProgram(kProgramId
, vertex_shader_
,
195 fragment_shader_
, NULL
, varyings_
, GL_NONE
,
196 base::Bind(&MemoryProgramCacheTest::ShaderCacheCb
,
197 base::Unretained(this)));
199 EXPECT_EQ(ProgramCache::LINK_SUCCEEDED
, cache_
->GetLinkedProgramStatus(
200 vertex_shader_
->last_compiled_signature(),
201 fragment_shader_
->last_compiled_signature(),
202 NULL
, varyings_
, GL_NONE
));
203 EXPECT_EQ(1, shader_cache_count());
206 TEST_F(MemoryProgramCacheTest
, LoadProgram
) {
207 const GLenum kFormat
= 1;
208 const int kProgramId
= 10;
209 const int kBinaryLength
= 20;
210 char test_binary
[kBinaryLength
];
211 for (int i
= 0; i
< kBinaryLength
; ++i
) {
214 ProgramBinaryEmulator
emulator(kBinaryLength
, kFormat
, test_binary
);
216 SetExpectationsForSaveLinkedProgram(kProgramId
, &emulator
);
217 cache_
->SaveLinkedProgram(kProgramId
, vertex_shader_
,
218 fragment_shader_
, NULL
, varyings_
, GL_NONE
,
219 base::Bind(&MemoryProgramCacheTest::ShaderCacheCb
,
220 base::Unretained(this)));
222 EXPECT_EQ(ProgramCache::LINK_SUCCEEDED
, cache_
->GetLinkedProgramStatus(
223 vertex_shader_
->last_compiled_signature(),
224 fragment_shader_
->last_compiled_signature(),
225 NULL
, varyings_
, GL_NONE
));
226 EXPECT_EQ(1, shader_cache_count());
230 cache_
->LoadProgram(shader_cache_shader());
231 EXPECT_EQ(ProgramCache::LINK_SUCCEEDED
, cache_
->GetLinkedProgramStatus(
232 vertex_shader_
->last_compiled_signature(),
233 fragment_shader_
->last_compiled_signature(),
234 NULL
, varyings_
, GL_NONE
));
237 TEST_F(MemoryProgramCacheTest
, CacheLoadMatchesSave
) {
238 const GLenum kFormat
= 1;
239 const int kProgramId
= 10;
240 const int kBinaryLength
= 20;
241 char test_binary
[kBinaryLength
];
242 for (int i
= 0; i
< kBinaryLength
; ++i
) {
245 ProgramBinaryEmulator
emulator(kBinaryLength
, kFormat
, test_binary
);
247 SetExpectationsForSaveLinkedProgram(kProgramId
, &emulator
);
248 cache_
->SaveLinkedProgram(kProgramId
, vertex_shader_
,
249 fragment_shader_
, NULL
, varyings_
, GL_NONE
,
250 base::Bind(&MemoryProgramCacheTest::ShaderCacheCb
,
251 base::Unretained(this)));
252 EXPECT_EQ(1, shader_cache_count());
254 AttributeMap vertex_attrib_map
= vertex_shader_
->attrib_map();
255 UniformMap vertex_uniform_map
= vertex_shader_
->uniform_map();
256 VaryingMap vertex_varying_map
= vertex_shader_
->varying_map();
257 AttributeMap fragment_attrib_map
= fragment_shader_
->attrib_map();
258 UniformMap fragment_uniform_map
= fragment_shader_
->uniform_map();
259 VaryingMap fragment_varying_map
= fragment_shader_
->varying_map();
261 vertex_shader_
->set_attrib_map(AttributeMap());
262 vertex_shader_
->set_uniform_map(UniformMap());
263 vertex_shader_
->set_varying_map(VaryingMap());
264 fragment_shader_
->set_attrib_map(AttributeMap());
265 fragment_shader_
->set_uniform_map(UniformMap());
266 fragment_shader_
->set_varying_map(VaryingMap());
268 SetExpectationsForLoadLinkedProgram(kProgramId
, &emulator
);
270 EXPECT_EQ(ProgramCache::PROGRAM_LOAD_SUCCESS
, cache_
->LoadLinkedProgram(
277 base::Bind(&MemoryProgramCacheTest::ShaderCacheCb
,
278 base::Unretained(this))));
280 // apparently the hash_map implementation on android doesn't have the
282 #if !defined(OS_ANDROID)
283 EXPECT_EQ(vertex_attrib_map
, vertex_shader_
->attrib_map());
284 EXPECT_EQ(vertex_uniform_map
, vertex_shader_
->uniform_map());
285 EXPECT_EQ(vertex_varying_map
, vertex_shader_
->varying_map());
286 EXPECT_EQ(fragment_attrib_map
, fragment_shader_
->attrib_map());
287 EXPECT_EQ(fragment_uniform_map
, fragment_shader_
->uniform_map());
288 EXPECT_EQ(fragment_varying_map
, fragment_shader_
->varying_map());
292 TEST_F(MemoryProgramCacheTest
, LoadProgramMatchesSave
) {
293 const GLenum kFormat
= 1;
294 const int kProgramId
= 10;
295 const int kBinaryLength
= 20;
296 char test_binary
[kBinaryLength
];
297 for (int i
= 0; i
< kBinaryLength
; ++i
) {
300 ProgramBinaryEmulator
emulator(kBinaryLength
, kFormat
, test_binary
);
302 SetExpectationsForSaveLinkedProgram(kProgramId
, &emulator
);
303 cache_
->SaveLinkedProgram(kProgramId
, vertex_shader_
,
304 fragment_shader_
, NULL
, varyings_
, GL_NONE
,
305 base::Bind(&MemoryProgramCacheTest::ShaderCacheCb
,
306 base::Unretained(this)));
307 EXPECT_EQ(1, shader_cache_count());
309 AttributeMap vertex_attrib_map
= vertex_shader_
->attrib_map();
310 UniformMap vertex_uniform_map
= vertex_shader_
->uniform_map();
311 VaryingMap vertex_varying_map
= vertex_shader_
->varying_map();
312 AttributeMap fragment_attrib_map
= fragment_shader_
->attrib_map();
313 UniformMap fragment_uniform_map
= fragment_shader_
->uniform_map();
314 VaryingMap fragment_varying_map
= fragment_shader_
->varying_map();
316 vertex_shader_
->set_attrib_map(AttributeMap());
317 vertex_shader_
->set_uniform_map(UniformMap());
318 vertex_shader_
->set_varying_map(VaryingMap());
319 fragment_shader_
->set_attrib_map(AttributeMap());
320 fragment_shader_
->set_uniform_map(UniformMap());
321 fragment_shader_
->set_varying_map(VaryingMap());
323 SetExpectationsForLoadLinkedProgram(kProgramId
, &emulator
);
326 cache_
->LoadProgram(shader_cache_shader());
328 EXPECT_EQ(ProgramCache::PROGRAM_LOAD_SUCCESS
, cache_
->LoadLinkedProgram(
335 base::Bind(&MemoryProgramCacheTest::ShaderCacheCb
,
336 base::Unretained(this))));
338 // apparently the hash_map implementation on android doesn't have the
340 #if !defined(OS_ANDROID)
341 EXPECT_EQ(vertex_attrib_map
, vertex_shader_
->attrib_map());
342 EXPECT_EQ(vertex_uniform_map
, vertex_shader_
->uniform_map());
343 EXPECT_EQ(vertex_varying_map
, vertex_shader_
->varying_map());
344 EXPECT_EQ(fragment_attrib_map
, fragment_shader_
->attrib_map());
345 EXPECT_EQ(fragment_uniform_map
, fragment_shader_
->uniform_map());
346 EXPECT_EQ(fragment_varying_map
, fragment_shader_
->varying_map());
350 TEST_F(MemoryProgramCacheTest
, LoadFailOnLinkFalse
) {
351 const GLenum kFormat
= 1;
352 const int kProgramId
= 10;
353 const int kBinaryLength
= 20;
354 char test_binary
[kBinaryLength
];
355 for (int i
= 0; i
< kBinaryLength
; ++i
) {
358 ProgramBinaryEmulator
emulator(kBinaryLength
, kFormat
, test_binary
);
360 SetExpectationsForSaveLinkedProgram(kProgramId
, &emulator
);
361 cache_
->SaveLinkedProgram(kProgramId
, vertex_shader_
,
362 fragment_shader_
, NULL
, varyings_
, GL_NONE
,
363 base::Bind(&MemoryProgramCacheTest::ShaderCacheCb
,
364 base::Unretained(this)));
366 SetExpectationsForLoadLinkedProgramFailure(kProgramId
, &emulator
);
367 EXPECT_EQ(ProgramCache::PROGRAM_LOAD_FAILURE
, cache_
->LoadLinkedProgram(
374 base::Bind(&MemoryProgramCacheTest::ShaderCacheCb
,
375 base::Unretained(this))));
378 TEST_F(MemoryProgramCacheTest
, LoadFailOnDifferentSource
) {
379 const GLenum kFormat
= 1;
380 const int kProgramId
= 10;
381 const int kBinaryLength
= 20;
382 char test_binary
[kBinaryLength
];
383 for (int i
= 0; i
< kBinaryLength
; ++i
) {
386 ProgramBinaryEmulator
emulator(kBinaryLength
, kFormat
, test_binary
);
388 SetExpectationsForSaveLinkedProgram(kProgramId
, &emulator
);
389 cache_
->SaveLinkedProgram(kProgramId
, vertex_shader_
,
390 fragment_shader_
, NULL
, varyings_
, GL_NONE
,
391 base::Bind(&MemoryProgramCacheTest::ShaderCacheCb
,
392 base::Unretained(this)));
394 const std::string vertex_orig_source
= vertex_shader_
->last_compiled_source();
395 vertex_shader_
->set_source("different!");
396 TestHelper::SetShaderStates(gl_
.get(), vertex_shader_
, true);
397 EXPECT_EQ(ProgramCache::PROGRAM_LOAD_FAILURE
, cache_
->LoadLinkedProgram(
404 base::Bind(&MemoryProgramCacheTest::ShaderCacheCb
,
405 base::Unretained(this))));
407 vertex_shader_
->set_source(vertex_orig_source
);
408 TestHelper::SetShaderStates(gl_
.get(), vertex_shader_
, true);
409 fragment_shader_
->set_source("different!");
410 TestHelper::SetShaderStates(gl_
.get(), fragment_shader_
, true);
411 EXPECT_EQ(ProgramCache::PROGRAM_LOAD_FAILURE
, cache_
->LoadLinkedProgram(
418 base::Bind(&MemoryProgramCacheTest::ShaderCacheCb
,
419 base::Unretained(this))));
422 TEST_F(MemoryProgramCacheTest
, LoadFailOnDifferentMap
) {
423 const GLenum kFormat
= 1;
424 const int kProgramId
= 10;
425 const int kBinaryLength
= 20;
426 char test_binary
[kBinaryLength
];
427 for (int i
= 0; i
< kBinaryLength
; ++i
) {
430 ProgramBinaryEmulator
emulator(kBinaryLength
, kFormat
, test_binary
);
432 SetExpectationsForSaveLinkedProgram(kProgramId
, &emulator
);
433 ProgramCache::LocationMap binding_map
;
434 binding_map
["test"] = 512;
435 cache_
->SaveLinkedProgram(kProgramId
,
441 base::Bind(&MemoryProgramCacheTest::ShaderCacheCb
,
442 base::Unretained(this)));
444 binding_map
["different!"] = 59;
445 EXPECT_EQ(ProgramCache::PROGRAM_LOAD_FAILURE
, cache_
->LoadLinkedProgram(
452 base::Bind(&MemoryProgramCacheTest::ShaderCacheCb
,
453 base::Unretained(this))));
454 EXPECT_EQ(ProgramCache::PROGRAM_LOAD_FAILURE
, cache_
->LoadLinkedProgram(
461 base::Bind(&MemoryProgramCacheTest::ShaderCacheCb
,
462 base::Unretained(this))));
465 TEST_F(MemoryProgramCacheTest
, LoadFailOnDifferentTransformFeedbackVaryings
) {
466 const GLenum kFormat
= 1;
467 const int kProgramId
= 10;
468 const int kBinaryLength
= 20;
469 char test_binary
[kBinaryLength
];
470 for (int i
= 0; i
< kBinaryLength
; ++i
) {
473 ProgramBinaryEmulator
emulator(kBinaryLength
, kFormat
, test_binary
);
475 SetExpectationsForSaveLinkedProgram(kProgramId
, &emulator
);
476 varyings_
.push_back("test");
477 cache_
->SaveLinkedProgram(kProgramId
,
482 GL_INTERLEAVED_ATTRIBS
,
483 base::Bind(&MemoryProgramCacheTest::ShaderCacheCb
,
484 base::Unretained(this)));
486 EXPECT_EQ(ProgramCache::PROGRAM_LOAD_FAILURE
, cache_
->LoadLinkedProgram(
493 base::Bind(&MemoryProgramCacheTest::ShaderCacheCb
,
494 base::Unretained(this))));
496 varyings_
.push_back("different!");
497 EXPECT_EQ(ProgramCache::PROGRAM_LOAD_FAILURE
, cache_
->LoadLinkedProgram(
503 GL_INTERLEAVED_ATTRIBS
,
504 base::Bind(&MemoryProgramCacheTest::ShaderCacheCb
,
505 base::Unretained(this))));
508 TEST_F(MemoryProgramCacheTest
, MemoryProgramCacheEviction
) {
509 const GLenum kFormat
= 1;
510 const int kProgramId
= 10;
511 const int kBinaryLength
= 20;
512 char test_binary
[kBinaryLength
];
513 for (int i
= 0; i
< kBinaryLength
; ++i
) {
516 ProgramBinaryEmulator
emulator1(kBinaryLength
, kFormat
, test_binary
);
519 SetExpectationsForSaveLinkedProgram(kProgramId
, &emulator1
);
520 cache_
->SaveLinkedProgram(kProgramId
, vertex_shader_
,
521 fragment_shader_
, NULL
, varyings_
, GL_NONE
,
522 base::Bind(&MemoryProgramCacheTest::ShaderCacheCb
,
523 base::Unretained(this)));
525 const int kEvictingProgramId
= 11;
526 const GLuint kEvictingBinaryLength
= kCacheSizeBytes
- kBinaryLength
+ 1;
528 // save old source and modify for new program
529 const std::string
& old_sig
= fragment_shader_
->last_compiled_signature();
530 fragment_shader_
->set_source("al sdfkjdk");
531 TestHelper::SetShaderStates(gl_
.get(), fragment_shader_
, true);
533 scoped_ptr
<char[]> bigTestBinary
=
534 scoped_ptr
<char[]>(new char[kEvictingBinaryLength
]);
535 for (size_t i
= 0; i
< kEvictingBinaryLength
; ++i
) {
536 bigTestBinary
[i
] = i
% 250;
538 ProgramBinaryEmulator
emulator2(kEvictingBinaryLength
,
540 bigTestBinary
.get());
542 SetExpectationsForSaveLinkedProgram(kEvictingProgramId
, &emulator2
);
543 cache_
->SaveLinkedProgram(kEvictingProgramId
,
549 base::Bind(&MemoryProgramCacheTest::ShaderCacheCb
,
550 base::Unretained(this)));
552 EXPECT_EQ(ProgramCache::LINK_SUCCEEDED
, cache_
->GetLinkedProgramStatus(
553 vertex_shader_
->last_compiled_signature(),
554 fragment_shader_
->last_compiled_signature(),
555 NULL
, varyings_
, GL_NONE
));
556 EXPECT_EQ(ProgramCache::LINK_UNKNOWN
, cache_
->GetLinkedProgramStatus(
558 fragment_shader_
->last_compiled_signature(),
559 NULL
, varyings_
, GL_NONE
));
562 TEST_F(MemoryProgramCacheTest
, SaveCorrectProgram
) {
563 const GLenum kFormat
= 1;
564 const int kProgramId
= 10;
565 const int kBinaryLength
= 20;
566 char test_binary
[kBinaryLength
];
567 for (int i
= 0; i
< kBinaryLength
; ++i
) {
570 ProgramBinaryEmulator
emulator1(kBinaryLength
, kFormat
, test_binary
);
572 vertex_shader_
->set_source("different!");
573 SetExpectationsForSaveLinkedProgram(kProgramId
, &emulator1
);
574 cache_
->SaveLinkedProgram(kProgramId
, vertex_shader_
,
575 fragment_shader_
, NULL
, varyings_
, GL_NONE
,
576 base::Bind(&MemoryProgramCacheTest::ShaderCacheCb
,
577 base::Unretained(this)));
579 EXPECT_EQ(ProgramCache::LINK_SUCCEEDED
, cache_
->GetLinkedProgramStatus(
580 vertex_shader_
->last_compiled_signature(),
581 fragment_shader_
->last_compiled_signature(),
582 NULL
, varyings_
, GL_NONE
));
585 TEST_F(MemoryProgramCacheTest
, LoadCorrectProgram
) {
586 const GLenum kFormat
= 1;
587 const int kProgramId
= 10;
588 const int kBinaryLength
= 20;
589 char test_binary
[kBinaryLength
];
590 for (int i
= 0; i
< kBinaryLength
; ++i
) {
593 ProgramBinaryEmulator
emulator(kBinaryLength
, kFormat
, test_binary
);
595 SetExpectationsForSaveLinkedProgram(kProgramId
, &emulator
);
596 cache_
->SaveLinkedProgram(kProgramId
, vertex_shader_
,
597 fragment_shader_
, NULL
, varyings_
, GL_NONE
,
598 base::Bind(&MemoryProgramCacheTest::ShaderCacheCb
,
599 base::Unretained(this)));
601 EXPECT_EQ(ProgramCache::LINK_SUCCEEDED
, cache_
->GetLinkedProgramStatus(
602 vertex_shader_
->last_compiled_signature(),
603 fragment_shader_
->last_compiled_signature(),
604 NULL
, varyings_
, GL_NONE
));
606 SetExpectationsForLoadLinkedProgram(kProgramId
, &emulator
);
608 fragment_shader_
->set_source("different!");
609 EXPECT_EQ(ProgramCache::PROGRAM_LOAD_SUCCESS
, cache_
->LoadLinkedProgram(
616 base::Bind(&MemoryProgramCacheTest::ShaderCacheCb
,
617 base::Unretained(this))));
620 TEST_F(MemoryProgramCacheTest
, OverwriteOnNewSave
) {
621 const GLenum kFormat
= 1;
622 const int kProgramId
= 10;
623 const int kBinaryLength
= 20;
624 char test_binary
[kBinaryLength
];
625 for (int i
= 0; i
< kBinaryLength
; ++i
) {
628 ProgramBinaryEmulator
emulator(kBinaryLength
, kFormat
, test_binary
);
630 SetExpectationsForSaveLinkedProgram(kProgramId
, &emulator
);
631 cache_
->SaveLinkedProgram(kProgramId
, vertex_shader_
,
632 fragment_shader_
, NULL
, varyings_
, GL_NONE
,
633 base::Bind(&MemoryProgramCacheTest::ShaderCacheCb
,
634 base::Unretained(this)));
637 char test_binary2
[kBinaryLength
];
638 for (int i
= 0; i
< kBinaryLength
; ++i
) {
639 test_binary2
[i
] = (i
*2) % 250;
641 ProgramBinaryEmulator
emulator2(kBinaryLength
, kFormat
, test_binary2
);
642 SetExpectationsForSaveLinkedProgram(kProgramId
, &emulator2
);
643 cache_
->SaveLinkedProgram(kProgramId
, vertex_shader_
,
644 fragment_shader_
, NULL
, varyings_
, GL_NONE
,
645 base::Bind(&MemoryProgramCacheTest::ShaderCacheCb
,
646 base::Unretained(this)));
648 SetExpectationsForLoadLinkedProgram(kProgramId
, &emulator2
);
649 EXPECT_EQ(ProgramCache::PROGRAM_LOAD_SUCCESS
, cache_
->LoadLinkedProgram(
656 base::Bind(&MemoryProgramCacheTest::ShaderCacheCb
,
657 base::Unretained(this))));