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::ElementsAreArray
;
20 using ::testing::Invoke
;
21 using ::testing::SetArgPointee
;
22 using ::testing::SetArrayArgument
;
25 typedef gpu::gles2::ShaderTranslator::VariableMap VariableMap
;
26 } // anonymous namespace
31 class ProgramBinaryEmulator
{
33 ProgramBinaryEmulator(GLsizei length
,
40 void GetProgramBinary(GLuint program
,
49 memcpy(binary
, binary_
, length_
);
52 void ProgramBinary(GLuint program
,
56 // format and length are verified by matcher
57 EXPECT_EQ(0, memcmp(binary_
, binary
, length
));
60 GLsizei
length() const { return length_
; }
61 GLenum
format() const { return format_
; }
62 const char* binary() const { return binary_
; }
70 class MemoryProgramCacheTest
: public GpuServiceTest
{
72 static const size_t kCacheSizeBytes
= 1024;
73 static const GLuint kVertexShaderClientId
= 90;
74 static const GLuint kVertexShaderServiceId
= 100;
75 static const GLuint kFragmentShaderClientId
= 91;
76 static const GLuint kFragmentShaderServiceId
= 100;
78 MemoryProgramCacheTest()
79 : cache_(new MemoryProgramCache(kCacheSizeBytes
)),
81 fragment_shader_(NULL
),
82 shader_cache_count_(0) { }
83 virtual ~MemoryProgramCacheTest() {
84 shader_manager_
.Destroy(false);
87 void ShaderCacheCb(const std::string
& key
, const std::string
& shader
) {
88 shader_cache_count_
++;
89 shader_cache_shader_
= shader
;
92 int32
shader_cache_count() { return shader_cache_count_
; }
93 const std::string
& shader_cache_shader() { return shader_cache_shader_
; }
96 virtual void SetUp() {
97 GpuServiceTest::SetUp();
99 vertex_shader_
= shader_manager_
.CreateShader(kVertexShaderClientId
,
100 kVertexShaderServiceId
,
102 fragment_shader_
= shader_manager_
.CreateShader(
103 kFragmentShaderClientId
,
104 kFragmentShaderServiceId
,
106 ASSERT_TRUE(vertex_shader_
!= NULL
);
107 ASSERT_TRUE(fragment_shader_
!= NULL
);
108 typedef ShaderTranslatorInterface::VariableInfo VariableInfo
;
109 typedef ShaderTranslator::VariableMap VariableMap
;
110 VariableMap vertex_attrib_map
;
111 VariableMap vertex_uniform_map
;
112 VariableMap vertex_varying_map
;
113 VariableMap fragment_attrib_map
;
114 VariableMap fragment_uniform_map
;
115 VariableMap fragment_varying_map
;
117 vertex_attrib_map
["a"] = VariableInfo(1, 34, SH_PRECISION_LOWP
, 0, "a");
118 vertex_uniform_map
["a"] = VariableInfo(0, 10, SH_PRECISION_MEDIUMP
, 1, "a");
119 vertex_uniform_map
["b"] = VariableInfo(2, 3114, SH_PRECISION_HIGHP
, 1, "b");
120 vertex_varying_map
["c"] = VariableInfo(3, 2, SH_PRECISION_HIGHP
, 1, "c");
121 fragment_attrib_map
["jjjbb"] =
122 VariableInfo(463, 1114, SH_PRECISION_MEDIUMP
, 0, "jjjbb");
123 fragment_uniform_map
["k"] =
124 VariableInfo(10, 34413, SH_PRECISION_MEDIUMP
, 1, "k");
125 fragment_varying_map
["c"] = VariableInfo(3, 2, SH_PRECISION_HIGHP
, 1, "c");
127 vertex_shader_
->set_source("bbbalsldkdkdkd");
128 fragment_shader_
->set_source("bbbal sldkdkdkas 134 ad");
130 TestHelper::SetShaderStates(
131 gl_
.get(), vertex_shader_
, true, NULL
, NULL
,
132 &vertex_attrib_map
, &vertex_uniform_map
, &vertex_varying_map
,
134 TestHelper::SetShaderStates(
135 gl_
.get(), fragment_shader_
, true, NULL
, NULL
,
136 &fragment_attrib_map
, &fragment_uniform_map
, &fragment_varying_map
,
140 void SetExpectationsForSaveLinkedProgram(
141 const GLint program_id
,
142 ProgramBinaryEmulator
* emulator
) const {
143 EXPECT_CALL(*gl_
.get(),
144 GetProgramiv(program_id
, GL_PROGRAM_BINARY_LENGTH_OES
, _
))
145 .WillOnce(SetArgPointee
<2>(emulator
->length()));
146 EXPECT_CALL(*gl_
.get(),
147 GetProgramBinary(program_id
, emulator
->length(), _
, _
, _
))
148 .WillOnce(Invoke(emulator
, &ProgramBinaryEmulator::GetProgramBinary
));
151 void SetExpectationsForLoadLinkedProgram(
152 const GLint program_id
,
153 ProgramBinaryEmulator
* emulator
) const {
154 EXPECT_CALL(*gl_
.get(),
155 ProgramBinary(program_id
,
159 .WillOnce(Invoke(emulator
, &ProgramBinaryEmulator::ProgramBinary
));
160 EXPECT_CALL(*gl_
.get(),
161 GetProgramiv(program_id
, GL_LINK_STATUS
, _
))
162 .WillOnce(SetArgPointee
<2>(GL_TRUE
));
165 void SetExpectationsForLoadLinkedProgramFailure(
166 const GLint program_id
,
167 ProgramBinaryEmulator
* emulator
) const {
168 EXPECT_CALL(*gl_
.get(),
169 ProgramBinary(program_id
,
173 .WillOnce(Invoke(emulator
, &ProgramBinaryEmulator::ProgramBinary
));
174 EXPECT_CALL(*gl_
.get(),
175 GetProgramiv(program_id
, GL_LINK_STATUS
, _
))
176 .WillOnce(SetArgPointee
<2>(GL_FALSE
));
179 scoped_ptr
<MemoryProgramCache
> cache_
;
180 ShaderManager shader_manager_
;
181 Shader
* vertex_shader_
;
182 Shader
* fragment_shader_
;
183 int32 shader_cache_count_
;
184 std::string shader_cache_shader_
;
187 TEST_F(MemoryProgramCacheTest
, CacheSave
) {
188 const GLenum kFormat
= 1;
189 const int kProgramId
= 10;
190 const int kBinaryLength
= 20;
191 char test_binary
[kBinaryLength
];
192 for (int i
= 0; i
< kBinaryLength
; ++i
) {
195 ProgramBinaryEmulator
emulator(kBinaryLength
, kFormat
, test_binary
);
197 SetExpectationsForSaveLinkedProgram(kProgramId
, &emulator
);
198 cache_
->SaveLinkedProgram(kProgramId
, vertex_shader_
, NULL
,
199 fragment_shader_
, NULL
, NULL
,
200 base::Bind(&MemoryProgramCacheTest::ShaderCacheCb
,
201 base::Unretained(this)));
203 EXPECT_EQ(ProgramCache::LINK_SUCCEEDED
, cache_
->GetLinkedProgramStatus(
204 vertex_shader_
->signature_source(),
206 fragment_shader_
->signature_source(),
209 EXPECT_EQ(1, shader_cache_count());
212 TEST_F(MemoryProgramCacheTest
, LoadProgram
) {
213 const GLenum kFormat
= 1;
214 const int kProgramId
= 10;
215 const int kBinaryLength
= 20;
216 char test_binary
[kBinaryLength
];
217 for (int i
= 0; i
< kBinaryLength
; ++i
) {
220 ProgramBinaryEmulator
emulator(kBinaryLength
, kFormat
, test_binary
);
222 SetExpectationsForSaveLinkedProgram(kProgramId
, &emulator
);
223 cache_
->SaveLinkedProgram(kProgramId
, vertex_shader_
, NULL
,
224 fragment_shader_
, NULL
, NULL
,
225 base::Bind(&MemoryProgramCacheTest::ShaderCacheCb
,
226 base::Unretained(this)));
228 EXPECT_EQ(ProgramCache::LINK_SUCCEEDED
, cache_
->GetLinkedProgramStatus(
229 vertex_shader_
->signature_source(),
231 fragment_shader_
->signature_source(),
234 EXPECT_EQ(1, shader_cache_count());
238 cache_
->LoadProgram(shader_cache_shader());
239 EXPECT_EQ(ProgramCache::LINK_SUCCEEDED
, cache_
->GetLinkedProgramStatus(
240 vertex_shader_
->signature_source(),
242 fragment_shader_
->signature_source(),
247 TEST_F(MemoryProgramCacheTest
, CacheLoadMatchesSave
) {
248 const GLenum kFormat
= 1;
249 const int kProgramId
= 10;
250 const int kBinaryLength
= 20;
251 char test_binary
[kBinaryLength
];
252 for (int i
= 0; i
< kBinaryLength
; ++i
) {
255 ProgramBinaryEmulator
emulator(kBinaryLength
, kFormat
, test_binary
);
257 SetExpectationsForSaveLinkedProgram(kProgramId
, &emulator
);
258 cache_
->SaveLinkedProgram(kProgramId
, vertex_shader_
, NULL
,
259 fragment_shader_
, NULL
, NULL
,
260 base::Bind(&MemoryProgramCacheTest::ShaderCacheCb
,
261 base::Unretained(this)));
262 EXPECT_EQ(1, shader_cache_count());
264 VariableMap vertex_attrib_map
= vertex_shader_
->attrib_map();
265 VariableMap vertex_uniform_map
= vertex_shader_
->uniform_map();
266 VariableMap vertex_varying_map
= vertex_shader_
->varying_map();
267 VariableMap fragment_attrib_map
= fragment_shader_
->attrib_map();
268 VariableMap fragment_uniform_map
= fragment_shader_
->uniform_map();
269 VariableMap fragment_varying_map
= fragment_shader_
->varying_map();
271 vertex_shader_
->set_attrib_map(VariableMap());
272 vertex_shader_
->set_uniform_map(VariableMap());
273 vertex_shader_
->set_varying_map(VariableMap());
274 fragment_shader_
->set_attrib_map(VariableMap());
275 fragment_shader_
->set_uniform_map(VariableMap());
276 fragment_shader_
->set_varying_map(VariableMap());
278 SetExpectationsForLoadLinkedProgram(kProgramId
, &emulator
);
280 EXPECT_EQ(ProgramCache::PROGRAM_LOAD_SUCCESS
, cache_
->LoadLinkedProgram(
287 base::Bind(&MemoryProgramCacheTest::ShaderCacheCb
,
288 base::Unretained(this))));
290 // apparently the hash_map implementation on android doesn't have the
292 #if !defined(OS_ANDROID)
293 EXPECT_EQ(vertex_attrib_map
, vertex_shader_
->attrib_map());
294 EXPECT_EQ(vertex_uniform_map
, vertex_shader_
->uniform_map());
295 EXPECT_EQ(vertex_varying_map
, vertex_shader_
->varying_map());
296 EXPECT_EQ(fragment_attrib_map
, fragment_shader_
->attrib_map());
297 EXPECT_EQ(fragment_uniform_map
, fragment_shader_
->uniform_map());
298 EXPECT_EQ(fragment_varying_map
, fragment_shader_
->varying_map());
302 TEST_F(MemoryProgramCacheTest
, LoadProgramMatchesSave
) {
303 const GLenum kFormat
= 1;
304 const int kProgramId
= 10;
305 const int kBinaryLength
= 20;
306 char test_binary
[kBinaryLength
];
307 for (int i
= 0; i
< kBinaryLength
; ++i
) {
310 ProgramBinaryEmulator
emulator(kBinaryLength
, kFormat
, test_binary
);
312 SetExpectationsForSaveLinkedProgram(kProgramId
, &emulator
);
313 cache_
->SaveLinkedProgram(kProgramId
, vertex_shader_
, NULL
,
314 fragment_shader_
, NULL
, NULL
,
315 base::Bind(&MemoryProgramCacheTest::ShaderCacheCb
,
316 base::Unretained(this)));
317 EXPECT_EQ(1, shader_cache_count());
319 VariableMap vertex_attrib_map
= vertex_shader_
->attrib_map();
320 VariableMap vertex_uniform_map
= vertex_shader_
->uniform_map();
321 VariableMap vertex_varying_map
= vertex_shader_
->varying_map();
322 VariableMap fragment_attrib_map
= fragment_shader_
->attrib_map();
323 VariableMap fragment_uniform_map
= fragment_shader_
->uniform_map();
324 VariableMap fragment_varying_map
= fragment_shader_
->varying_map();
326 vertex_shader_
->set_attrib_map(VariableMap());
327 vertex_shader_
->set_uniform_map(VariableMap());
328 vertex_shader_
->set_varying_map(VariableMap());
329 fragment_shader_
->set_attrib_map(VariableMap());
330 fragment_shader_
->set_uniform_map(VariableMap());
331 fragment_shader_
->set_varying_map(VariableMap());
333 SetExpectationsForLoadLinkedProgram(kProgramId
, &emulator
);
336 cache_
->LoadProgram(shader_cache_shader());
338 EXPECT_EQ(ProgramCache::PROGRAM_LOAD_SUCCESS
, cache_
->LoadLinkedProgram(
345 base::Bind(&MemoryProgramCacheTest::ShaderCacheCb
,
346 base::Unretained(this))));
348 // apparently the hash_map implementation on android doesn't have the
350 #if !defined(OS_ANDROID)
351 EXPECT_EQ(vertex_attrib_map
, vertex_shader_
->attrib_map());
352 EXPECT_EQ(vertex_uniform_map
, vertex_shader_
->uniform_map());
353 EXPECT_EQ(vertex_varying_map
, vertex_shader_
->varying_map());
354 EXPECT_EQ(fragment_attrib_map
, fragment_shader_
->attrib_map());
355 EXPECT_EQ(fragment_uniform_map
, fragment_shader_
->uniform_map());
356 EXPECT_EQ(fragment_varying_map
, fragment_shader_
->varying_map());
360 TEST_F(MemoryProgramCacheTest
, LoadFailOnLinkFalse
) {
361 const GLenum kFormat
= 1;
362 const int kProgramId
= 10;
363 const int kBinaryLength
= 20;
364 char test_binary
[kBinaryLength
];
365 for (int i
= 0; i
< kBinaryLength
; ++i
) {
368 ProgramBinaryEmulator
emulator(kBinaryLength
, kFormat
, test_binary
);
370 SetExpectationsForSaveLinkedProgram(kProgramId
, &emulator
);
371 cache_
->SaveLinkedProgram(kProgramId
, vertex_shader_
, NULL
,
372 fragment_shader_
, NULL
, NULL
,
373 base::Bind(&MemoryProgramCacheTest::ShaderCacheCb
,
374 base::Unretained(this)));
376 SetExpectationsForLoadLinkedProgramFailure(kProgramId
, &emulator
);
377 EXPECT_EQ(ProgramCache::PROGRAM_LOAD_FAILURE
, cache_
->LoadLinkedProgram(
384 base::Bind(&MemoryProgramCacheTest::ShaderCacheCb
,
385 base::Unretained(this))));
388 TEST_F(MemoryProgramCacheTest
, LoadFailOnDifferentSource
) {
389 const GLenum kFormat
= 1;
390 const int kProgramId
= 10;
391 const int kBinaryLength
= 20;
392 char test_binary
[kBinaryLength
];
393 for (int i
= 0; i
< kBinaryLength
; ++i
) {
396 ProgramBinaryEmulator
emulator(kBinaryLength
, kFormat
, test_binary
);
398 SetExpectationsForSaveLinkedProgram(kProgramId
, &emulator
);
399 cache_
->SaveLinkedProgram(kProgramId
, vertex_shader_
, NULL
,
400 fragment_shader_
, NULL
, NULL
,
401 base::Bind(&MemoryProgramCacheTest::ShaderCacheCb
,
402 base::Unretained(this)));
404 const std::string vertex_orig_source
= vertex_shader_
->signature_source();
405 vertex_shader_
->set_source("different!");
406 TestHelper::SetShaderStates(gl_
.get(), vertex_shader_
, true);
407 EXPECT_EQ(ProgramCache::PROGRAM_LOAD_FAILURE
, cache_
->LoadLinkedProgram(
414 base::Bind(&MemoryProgramCacheTest::ShaderCacheCb
,
415 base::Unretained(this))));
417 vertex_shader_
->set_source(vertex_orig_source
);
418 TestHelper::SetShaderStates(gl_
.get(), vertex_shader_
, true);
419 fragment_shader_
->set_source("different!");
420 TestHelper::SetShaderStates(gl_
.get(), fragment_shader_
, true);
421 EXPECT_EQ(ProgramCache::PROGRAM_LOAD_FAILURE
, cache_
->LoadLinkedProgram(
428 base::Bind(&MemoryProgramCacheTest::ShaderCacheCb
,
429 base::Unretained(this))));
432 TEST_F(MemoryProgramCacheTest
, LoadFailOnDifferentMap
) {
433 const GLenum kFormat
= 1;
434 const int kProgramId
= 10;
435 const int kBinaryLength
= 20;
436 char test_binary
[kBinaryLength
];
437 for (int i
= 0; i
< kBinaryLength
; ++i
) {
440 ProgramBinaryEmulator
emulator(kBinaryLength
, kFormat
, test_binary
);
442 SetExpectationsForSaveLinkedProgram(kProgramId
, &emulator
);
443 ProgramCache::LocationMap binding_map
;
444 binding_map
["test"] = 512;
445 cache_
->SaveLinkedProgram(kProgramId
,
451 base::Bind(&MemoryProgramCacheTest::ShaderCacheCb
,
452 base::Unretained(this)));
454 binding_map
["different!"] = 59;
455 EXPECT_EQ(ProgramCache::PROGRAM_LOAD_FAILURE
, cache_
->LoadLinkedProgram(
462 base::Bind(&MemoryProgramCacheTest::ShaderCacheCb
,
463 base::Unretained(this))));
464 EXPECT_EQ(ProgramCache::PROGRAM_LOAD_FAILURE
, cache_
->LoadLinkedProgram(
471 base::Bind(&MemoryProgramCacheTest::ShaderCacheCb
,
472 base::Unretained(this))));
475 TEST_F(MemoryProgramCacheTest
, MemoryProgramCacheEviction
) {
476 const GLenum kFormat
= 1;
477 const int kProgramId
= 10;
478 const int kBinaryLength
= 20;
479 char test_binary
[kBinaryLength
];
480 for (int i
= 0; i
< kBinaryLength
; ++i
) {
483 ProgramBinaryEmulator
emulator1(kBinaryLength
, kFormat
, test_binary
);
486 SetExpectationsForSaveLinkedProgram(kProgramId
, &emulator1
);
487 cache_
->SaveLinkedProgram(kProgramId
, vertex_shader_
, NULL
,
488 fragment_shader_
, NULL
, NULL
,
489 base::Bind(&MemoryProgramCacheTest::ShaderCacheCb
,
490 base::Unretained(this)));
492 const int kEvictingProgramId
= 11;
493 const GLuint kEvictingBinaryLength
= kCacheSizeBytes
- kBinaryLength
+ 1;
495 // save old source and modify for new program
496 const std::string
& old_source
= fragment_shader_
->signature_source();
497 fragment_shader_
->set_source("al sdfkjdk");
498 TestHelper::SetShaderStates(gl_
.get(), fragment_shader_
, true);
500 scoped_ptr
<char[]> bigTestBinary
=
501 scoped_ptr
<char[]>(new char[kEvictingBinaryLength
]);
502 for (size_t i
= 0; i
< kEvictingBinaryLength
; ++i
) {
503 bigTestBinary
[i
] = i
% 250;
505 ProgramBinaryEmulator
emulator2(kEvictingBinaryLength
,
507 bigTestBinary
.get());
509 SetExpectationsForSaveLinkedProgram(kEvictingProgramId
, &emulator2
);
510 cache_
->SaveLinkedProgram(kEvictingProgramId
,
516 base::Bind(&MemoryProgramCacheTest::ShaderCacheCb
,
517 base::Unretained(this)));
519 EXPECT_EQ(ProgramCache::LINK_SUCCEEDED
, cache_
->GetLinkedProgramStatus(
520 vertex_shader_
->signature_source(),
522 fragment_shader_
->signature_source(),
525 EXPECT_EQ(ProgramCache::LINK_UNKNOWN
, cache_
->GetLinkedProgramStatus(
528 fragment_shader_
->signature_source(),
533 TEST_F(MemoryProgramCacheTest
, SaveCorrectProgram
) {
534 const GLenum kFormat
= 1;
535 const int kProgramId
= 10;
536 const int kBinaryLength
= 20;
537 char test_binary
[kBinaryLength
];
538 for (int i
= 0; i
< kBinaryLength
; ++i
) {
541 ProgramBinaryEmulator
emulator1(kBinaryLength
, kFormat
, test_binary
);
543 vertex_shader_
->set_source("different!");
544 SetExpectationsForSaveLinkedProgram(kProgramId
, &emulator1
);
545 cache_
->SaveLinkedProgram(kProgramId
, vertex_shader_
, NULL
,
546 fragment_shader_
, NULL
, NULL
,
547 base::Bind(&MemoryProgramCacheTest::ShaderCacheCb
,
548 base::Unretained(this)));
550 EXPECT_EQ(ProgramCache::LINK_SUCCEEDED
, cache_
->GetLinkedProgramStatus(
551 vertex_shader_
->signature_source(),
553 fragment_shader_
->signature_source(),
558 TEST_F(MemoryProgramCacheTest
, LoadCorrectProgram
) {
559 const GLenum kFormat
= 1;
560 const int kProgramId
= 10;
561 const int kBinaryLength
= 20;
562 char test_binary
[kBinaryLength
];
563 for (int i
= 0; i
< kBinaryLength
; ++i
) {
566 ProgramBinaryEmulator
emulator(kBinaryLength
, kFormat
, test_binary
);
568 SetExpectationsForSaveLinkedProgram(kProgramId
, &emulator
);
569 cache_
->SaveLinkedProgram(kProgramId
, vertex_shader_
, NULL
,
570 fragment_shader_
, NULL
, NULL
,
571 base::Bind(&MemoryProgramCacheTest::ShaderCacheCb
,
572 base::Unretained(this)));
574 EXPECT_EQ(ProgramCache::LINK_SUCCEEDED
, cache_
->GetLinkedProgramStatus(
575 vertex_shader_
->signature_source(),
577 fragment_shader_
->signature_source(),
581 SetExpectationsForLoadLinkedProgram(kProgramId
, &emulator
);
583 fragment_shader_
->set_source("different!");
584 EXPECT_EQ(ProgramCache::PROGRAM_LOAD_SUCCESS
, cache_
->LoadLinkedProgram(
591 base::Bind(&MemoryProgramCacheTest::ShaderCacheCb
,
592 base::Unretained(this))));
595 TEST_F(MemoryProgramCacheTest
, OverwriteOnNewSave
) {
596 const GLenum kFormat
= 1;
597 const int kProgramId
= 10;
598 const int kBinaryLength
= 20;
599 char test_binary
[kBinaryLength
];
600 for (int i
= 0; i
< kBinaryLength
; ++i
) {
603 ProgramBinaryEmulator
emulator(kBinaryLength
, kFormat
, test_binary
);
605 SetExpectationsForSaveLinkedProgram(kProgramId
, &emulator
);
606 cache_
->SaveLinkedProgram(kProgramId
, vertex_shader_
, NULL
,
607 fragment_shader_
, NULL
, NULL
,
608 base::Bind(&MemoryProgramCacheTest::ShaderCacheCb
,
609 base::Unretained(this)));
612 char test_binary2
[kBinaryLength
];
613 for (int i
= 0; i
< kBinaryLength
; ++i
) {
614 test_binary2
[i
] = (i
*2) % 250;
616 ProgramBinaryEmulator
emulator2(kBinaryLength
, kFormat
, test_binary2
);
617 SetExpectationsForSaveLinkedProgram(kProgramId
, &emulator2
);
618 cache_
->SaveLinkedProgram(kProgramId
, vertex_shader_
, NULL
,
619 fragment_shader_
, NULL
, NULL
,
620 base::Bind(&MemoryProgramCacheTest::ShaderCacheCb
,
621 base::Unretained(this)));
623 SetExpectationsForLoadLinkedProgram(kProgramId
, &emulator2
);
624 EXPECT_EQ(ProgramCache::PROGRAM_LOAD_SUCCESS
, cache_
->LoadLinkedProgram(
631 base::Bind(&MemoryProgramCacheTest::ShaderCacheCb
,
632 base::Unretained(this))));