memory_program_cache_unittest.cc revision 90dce4d38c5ff5333bea97d859d4e484e27edf0c
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 16using ::testing::_; 17using ::testing::ElementsAreArray; 18using ::testing::Invoke; 19using ::testing::SetArgPointee; 20using ::testing::SetArrayArgument; 21 22namespace { 23typedef gpu::gles2::ShaderTranslator::VariableMap VariableMap; 24} // anonymous namespace 25 26namespace gpu { 27namespace gles2 { 28 29class 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 68class 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 fragment_attrib_map; 112 VariableMap fragment_uniform_map; 113 114 vertex_attrib_map["a"] = VariableInfo(1, 34, "a"); 115 vertex_uniform_map["a"] = VariableInfo(0, 10, "a"); 116 vertex_uniform_map["b"] = VariableInfo(2, 3114, "b"); 117 fragment_attrib_map["jjjbb"] = VariableInfo(463, 1114, "jjjbb"); 118 fragment_uniform_map["k"] = VariableInfo(10, 34413, "k"); 119 120 vertex_shader_->set_attrib_map(vertex_attrib_map); 121 vertex_shader_->set_uniform_map(vertex_uniform_map); 122 fragment_shader_->set_attrib_map(vertex_attrib_map); 123 fragment_shader_->set_uniform_map(vertex_uniform_map); 124 125 vertex_shader_->UpdateSource("bbbalsldkdkdkd"); 126 fragment_shader_->UpdateSource("bbbal sldkdkdkas 134 ad"); 127 vertex_shader_->FlagSourceAsCompiled(true); 128 fragment_shader_->FlagSourceAsCompiled(true); 129 130 vertex_shader_->SetStatus(true, NULL, NULL); 131 fragment_shader_->SetStatus(true, NULL, NULL); 132 } 133 134 virtual void TearDown() { 135 ::gfx::GLInterface::SetGLInterface(NULL); 136 gl_.reset(); 137 } 138 139 void SetExpectationsForSaveLinkedProgram( 140 const GLint program_id, 141 ProgramBinaryEmulator* emulator) const { 142 EXPECT_CALL(*gl_.get(), 143 GetProgramiv(program_id, GL_PROGRAM_BINARY_LENGTH_OES, _)) 144 .WillOnce(SetArgPointee<2>(emulator->length())); 145 EXPECT_CALL(*gl_.get(), 146 GetProgramBinary(program_id, emulator->length(), _, _, _)) 147 .WillOnce(Invoke(emulator, &ProgramBinaryEmulator::GetProgramBinary)); 148 } 149 150 void SetExpectationsForLoadLinkedProgram( 151 const GLint program_id, 152 ProgramBinaryEmulator* emulator) const { 153 EXPECT_CALL(*gl_.get(), 154 ProgramBinary(program_id, 155 emulator->format(), 156 _, 157 emulator->length())) 158 .WillOnce(Invoke(emulator, &ProgramBinaryEmulator::ProgramBinary)); 159 EXPECT_CALL(*gl_.get(), 160 GetProgramiv(program_id, GL_LINK_STATUS, _)) 161 .WillOnce(SetArgPointee<2>(GL_TRUE)); 162 } 163 164 void SetExpectationsForLoadLinkedProgramFailure( 165 const GLint program_id, 166 ProgramBinaryEmulator* emulator) const { 167 EXPECT_CALL(*gl_.get(), 168 ProgramBinary(program_id, 169 emulator->format(), 170 _, 171 emulator->length())) 172 .WillOnce(Invoke(emulator, &ProgramBinaryEmulator::ProgramBinary)); 173 EXPECT_CALL(*gl_.get(), 174 GetProgramiv(program_id, GL_LINK_STATUS, _)) 175 .WillOnce(SetArgPointee<2>(GL_FALSE)); 176 } 177 178 // Use StrictMock to make 100% sure we know how GL will be called. 179 scoped_ptr< ::testing::StrictMock<gfx::MockGLInterface> > gl_; 180 scoped_ptr<MemoryProgramCache> cache_; 181 ShaderManager shader_manager_; 182 Shader* vertex_shader_; 183 Shader* fragment_shader_; 184 int32 shader_cache_count_; 185 std::string shader_cache_shader_; 186}; 187 188TEST_F(MemoryProgramCacheTest, CacheSave) { 189 const GLenum kFormat = 1; 190 const int kProgramId = 10; 191 const int kBinaryLength = 20; 192 char test_binary[kBinaryLength]; 193 for (int i = 0; i < kBinaryLength; ++i) { 194 test_binary[i] = i; 195 } 196 ProgramBinaryEmulator emulator(kBinaryLength, kFormat, test_binary); 197 198 SetExpectationsForSaveLinkedProgram(kProgramId, &emulator); 199 cache_->SaveLinkedProgram(kProgramId, vertex_shader_, NULL, 200 fragment_shader_, NULL, NULL, 201 base::Bind(&MemoryProgramCacheTest::ShaderCacheCb, 202 base::Unretained(this))); 203 204 EXPECT_EQ(ProgramCache::LINK_SUCCEEDED, cache_->GetLinkedProgramStatus( 205 *vertex_shader_->deferred_compilation_source(), 206 NULL, 207 *fragment_shader_->deferred_compilation_source(), 208 NULL, 209 NULL)); 210 EXPECT_EQ(1, shader_cache_count()); 211} 212 213TEST_F(MemoryProgramCacheTest, LoadProgram) { 214 const GLenum kFormat = 1; 215 const int kProgramId = 10; 216 const int kBinaryLength = 20; 217 char test_binary[kBinaryLength]; 218 for (int i = 0; i < kBinaryLength; ++i) { 219 test_binary[i] = i; 220 } 221 ProgramBinaryEmulator emulator(kBinaryLength, kFormat, test_binary); 222 223 SetExpectationsForSaveLinkedProgram(kProgramId, &emulator); 224 cache_->SaveLinkedProgram(kProgramId, vertex_shader_, NULL, 225 fragment_shader_, NULL, NULL, 226 base::Bind(&MemoryProgramCacheTest::ShaderCacheCb, 227 base::Unretained(this))); 228 229 EXPECT_EQ(ProgramCache::LINK_SUCCEEDED, cache_->GetLinkedProgramStatus( 230 *vertex_shader_->deferred_compilation_source(), 231 NULL, 232 *fragment_shader_->deferred_compilation_source(), 233 NULL, 234 NULL)); 235 EXPECT_EQ(1, shader_cache_count()); 236 237 cache_->Clear(); 238 239 cache_->LoadProgram(shader_cache_shader()); 240 EXPECT_EQ(ProgramCache::LINK_SUCCEEDED, cache_->GetLinkedProgramStatus( 241 *vertex_shader_->deferred_compilation_source(), 242 NULL, 243 *fragment_shader_->deferred_compilation_source(), 244 NULL, 245 NULL)); 246} 247 248TEST_F(MemoryProgramCacheTest, CacheLoadMatchesSave) { 249 const GLenum kFormat = 1; 250 const int kProgramId = 10; 251 const int kBinaryLength = 20; 252 char test_binary[kBinaryLength]; 253 for (int i = 0; i < kBinaryLength; ++i) { 254 test_binary[i] = i; 255 } 256 ProgramBinaryEmulator emulator(kBinaryLength, kFormat, test_binary); 257 258 SetExpectationsForSaveLinkedProgram(kProgramId, &emulator); 259 cache_->SaveLinkedProgram(kProgramId, vertex_shader_, NULL, 260 fragment_shader_, NULL, NULL, 261 base::Bind(&MemoryProgramCacheTest::ShaderCacheCb, 262 base::Unretained(this))); 263 EXPECT_EQ(1, shader_cache_count()); 264 265 VariableMap vertex_attrib_map = vertex_shader_->attrib_map(); 266 VariableMap vertex_uniform_map = vertex_shader_->uniform_map(); 267 VariableMap fragment_attrib_map = fragment_shader_->attrib_map(); 268 VariableMap fragment_uniform_map = fragment_shader_->uniform_map(); 269 270 vertex_shader_->set_attrib_map(VariableMap()); 271 vertex_shader_->set_uniform_map(VariableMap()); 272 fragment_shader_->set_attrib_map(VariableMap()); 273 fragment_shader_->set_uniform_map(VariableMap()); 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_attrib_map, vertex_shader_->uniform_map()); 292 EXPECT_EQ(vertex_attrib_map, fragment_shader_->attrib_map()); 293 EXPECT_EQ(vertex_attrib_map, fragment_shader_->uniform_map()); 294#endif 295} 296 297TEST_F(MemoryProgramCacheTest, LoadProgramMatchesSave) { 298 const GLenum kFormat = 1; 299 const int kProgramId = 10; 300 const int kBinaryLength = 20; 301 char test_binary[kBinaryLength]; 302 for (int i = 0; i < kBinaryLength; ++i) { 303 test_binary[i] = i; 304 } 305 ProgramBinaryEmulator emulator(kBinaryLength, kFormat, test_binary); 306 307 SetExpectationsForSaveLinkedProgram(kProgramId, &emulator); 308 cache_->SaveLinkedProgram(kProgramId, vertex_shader_, NULL, 309 fragment_shader_, NULL, NULL, 310 base::Bind(&MemoryProgramCacheTest::ShaderCacheCb, 311 base::Unretained(this))); 312 EXPECT_EQ(1, shader_cache_count()); 313 314 VariableMap vertex_attrib_map = vertex_shader_->attrib_map(); 315 VariableMap vertex_uniform_map = vertex_shader_->uniform_map(); 316 VariableMap fragment_attrib_map = fragment_shader_->attrib_map(); 317 VariableMap fragment_uniform_map = fragment_shader_->uniform_map(); 318 319 vertex_shader_->set_attrib_map(VariableMap()); 320 vertex_shader_->set_uniform_map(VariableMap()); 321 fragment_shader_->set_attrib_map(VariableMap()); 322 fragment_shader_->set_uniform_map(VariableMap()); 323 324 SetExpectationsForLoadLinkedProgram(kProgramId, &emulator); 325 326 cache_->Clear(); 327 cache_->LoadProgram(shader_cache_shader()); 328 329 EXPECT_EQ(ProgramCache::PROGRAM_LOAD_SUCCESS, cache_->LoadLinkedProgram( 330 kProgramId, 331 vertex_shader_, 332 NULL, 333 fragment_shader_, 334 NULL, 335 NULL, 336 base::Bind(&MemoryProgramCacheTest::ShaderCacheCb, 337 base::Unretained(this)))); 338 339 // apparently the hash_map implementation on android doesn't have the 340 // equality operator 341#if !defined(OS_ANDROID) 342 EXPECT_EQ(vertex_attrib_map, vertex_shader_->attrib_map()); 343 EXPECT_EQ(vertex_attrib_map, vertex_shader_->uniform_map()); 344 EXPECT_EQ(vertex_attrib_map, fragment_shader_->attrib_map()); 345 EXPECT_EQ(vertex_attrib_map, fragment_shader_->uniform_map()); 346#endif 347} 348 349TEST_F(MemoryProgramCacheTest, LoadFailOnLinkFalse) { 350 const GLenum kFormat = 1; 351 const int kProgramId = 10; 352 const int kBinaryLength = 20; 353 char test_binary[kBinaryLength]; 354 for (int i = 0; i < kBinaryLength; ++i) { 355 test_binary[i] = i; 356 } 357 ProgramBinaryEmulator emulator(kBinaryLength, kFormat, test_binary); 358 359 SetExpectationsForSaveLinkedProgram(kProgramId, &emulator); 360 cache_->SaveLinkedProgram(kProgramId, vertex_shader_, NULL, 361 fragment_shader_, NULL, NULL, 362 base::Bind(&MemoryProgramCacheTest::ShaderCacheCb, 363 base::Unretained(this))); 364 365 SetExpectationsForLoadLinkedProgramFailure(kProgramId, &emulator); 366 EXPECT_EQ(ProgramCache::PROGRAM_LOAD_FAILURE, cache_->LoadLinkedProgram( 367 kProgramId, 368 vertex_shader_, 369 NULL, 370 fragment_shader_, 371 NULL, 372 NULL, 373 base::Bind(&MemoryProgramCacheTest::ShaderCacheCb, 374 base::Unretained(this)))); 375} 376 377TEST_F(MemoryProgramCacheTest, LoadFailOnDifferentSource) { 378 const GLenum kFormat = 1; 379 const int kProgramId = 10; 380 const int kBinaryLength = 20; 381 char test_binary[kBinaryLength]; 382 for (int i = 0; i < kBinaryLength; ++i) { 383 test_binary[i] = i; 384 } 385 ProgramBinaryEmulator emulator(kBinaryLength, kFormat, test_binary); 386 387 SetExpectationsForSaveLinkedProgram(kProgramId, &emulator); 388 cache_->SaveLinkedProgram(kProgramId, vertex_shader_, NULL, 389 fragment_shader_, NULL, NULL, 390 base::Bind(&MemoryProgramCacheTest::ShaderCacheCb, 391 base::Unretained(this))); 392 393 const std::string vertex_orig_source = 394 *vertex_shader_->deferred_compilation_source(); 395 vertex_shader_->UpdateSource("different!"); 396 vertex_shader_->FlagSourceAsCompiled(true); 397 EXPECT_EQ(ProgramCache::PROGRAM_LOAD_FAILURE, cache_->LoadLinkedProgram( 398 kProgramId, 399 vertex_shader_, 400 NULL, 401 fragment_shader_, 402 NULL, 403 NULL, 404 base::Bind(&MemoryProgramCacheTest::ShaderCacheCb, 405 base::Unretained(this)))); 406 407 vertex_shader_->UpdateSource(vertex_orig_source.c_str()); 408 vertex_shader_->FlagSourceAsCompiled(true); 409 fragment_shader_->UpdateSource("different!"); 410 fragment_shader_->FlagSourceAsCompiled(true); 411 EXPECT_EQ(ProgramCache::PROGRAM_LOAD_FAILURE, cache_->LoadLinkedProgram( 412 kProgramId, 413 vertex_shader_, 414 NULL, 415 fragment_shader_, 416 NULL, 417 NULL, 418 base::Bind(&MemoryProgramCacheTest::ShaderCacheCb, 419 base::Unretained(this)))); 420} 421 422TEST_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) { 428 test_binary[i] = i; 429 } 430 ProgramBinaryEmulator emulator(kBinaryLength, kFormat, test_binary); 431 432 SetExpectationsForSaveLinkedProgram(kProgramId, &emulator); 433 ProgramCache::LocationMap binding_map; 434 binding_map["test"] = 512; 435 cache_->SaveLinkedProgram(kProgramId, 436 vertex_shader_, 437 NULL, 438 fragment_shader_, 439 NULL, 440 &binding_map, 441 base::Bind(&MemoryProgramCacheTest::ShaderCacheCb, 442 base::Unretained(this))); 443 444 binding_map["different!"] = 59; 445 EXPECT_EQ(ProgramCache::PROGRAM_LOAD_FAILURE, cache_->LoadLinkedProgram( 446 kProgramId, 447 vertex_shader_, 448 NULL, 449 fragment_shader_, 450 NULL, 451 &binding_map, 452 base::Bind(&MemoryProgramCacheTest::ShaderCacheCb, 453 base::Unretained(this)))); 454 EXPECT_EQ(ProgramCache::PROGRAM_LOAD_FAILURE, cache_->LoadLinkedProgram( 455 kProgramId, 456 vertex_shader_, 457 NULL, 458 fragment_shader_, 459 NULL, 460 NULL, 461 base::Bind(&MemoryProgramCacheTest::ShaderCacheCb, 462 base::Unretained(this)))); 463} 464 465TEST_F(MemoryProgramCacheTest, MemoryProgramCacheEviction) { 466 typedef ShaderTranslator::VariableMap VariableMap; 467 const GLenum kFormat = 1; 468 const int kProgramId = 10; 469 const int kBinaryLength = 20; 470 char test_binary[kBinaryLength]; 471 for (int i = 0; i < kBinaryLength; ++i) { 472 test_binary[i] = i; 473 } 474 ProgramBinaryEmulator emulator1(kBinaryLength, kFormat, test_binary); 475 476 477 SetExpectationsForSaveLinkedProgram(kProgramId, &emulator1); 478 cache_->SaveLinkedProgram(kProgramId, vertex_shader_, NULL, 479 fragment_shader_, NULL, NULL, 480 base::Bind(&MemoryProgramCacheTest::ShaderCacheCb, 481 base::Unretained(this))); 482 483 const int kEvictingProgramId = 11; 484 const GLuint kEvictingBinaryLength = kCacheSizeBytes - kBinaryLength + 1; 485 486 // save old source and modify for new program 487 const std::string old_source = 488 *fragment_shader_->deferred_compilation_source(); 489 fragment_shader_->UpdateSource("al sdfkjdk"); 490 fragment_shader_->FlagSourceAsCompiled(true); 491 492 scoped_ptr<char[]> bigTestBinary = 493 scoped_ptr<char[]>(new char[kEvictingBinaryLength]); 494 for (size_t i = 0; i < kEvictingBinaryLength; ++i) { 495 bigTestBinary[i] = i % 250; 496 } 497 ProgramBinaryEmulator emulator2(kEvictingBinaryLength, 498 kFormat, 499 bigTestBinary.get()); 500 501 SetExpectationsForSaveLinkedProgram(kEvictingProgramId, &emulator2); 502 cache_->SaveLinkedProgram(kEvictingProgramId, 503 vertex_shader_, 504 NULL, 505 fragment_shader_, 506 NULL, 507 NULL, 508 base::Bind(&MemoryProgramCacheTest::ShaderCacheCb, 509 base::Unretained(this))); 510 511 EXPECT_EQ(ProgramCache::LINK_SUCCEEDED, cache_->GetLinkedProgramStatus( 512 *vertex_shader_->deferred_compilation_source(), 513 NULL, 514 *fragment_shader_->deferred_compilation_source(), 515 NULL, 516 NULL)); 517 EXPECT_EQ(ProgramCache::LINK_UNKNOWN, cache_->GetLinkedProgramStatus( 518 old_source, 519 NULL, 520 *fragment_shader_->deferred_compilation_source(), 521 NULL, 522 NULL)); 523} 524 525TEST_F(MemoryProgramCacheTest, SaveCorrectProgram) { 526 const GLenum kFormat = 1; 527 const int kProgramId = 10; 528 const int kBinaryLength = 20; 529 char test_binary[kBinaryLength]; 530 for (int i = 0; i < kBinaryLength; ++i) { 531 test_binary[i] = i; 532 } 533 ProgramBinaryEmulator emulator1(kBinaryLength, kFormat, test_binary); 534 535 vertex_shader_->UpdateSource("different!"); 536 SetExpectationsForSaveLinkedProgram(kProgramId, &emulator1); 537 cache_->SaveLinkedProgram(kProgramId, vertex_shader_, NULL, 538 fragment_shader_, NULL, NULL, 539 base::Bind(&MemoryProgramCacheTest::ShaderCacheCb, 540 base::Unretained(this))); 541 542 EXPECT_EQ(ProgramCache::LINK_SUCCEEDED, cache_->GetLinkedProgramStatus( 543 *vertex_shader_->deferred_compilation_source(), 544 NULL, 545 *fragment_shader_->deferred_compilation_source(), 546 NULL, 547 NULL)); 548} 549 550TEST_F(MemoryProgramCacheTest, LoadCorrectProgram) { 551 const GLenum kFormat = 1; 552 const int kProgramId = 10; 553 const int kBinaryLength = 20; 554 char test_binary[kBinaryLength]; 555 for (int i = 0; i < kBinaryLength; ++i) { 556 test_binary[i] = i; 557 } 558 ProgramBinaryEmulator emulator(kBinaryLength, kFormat, test_binary); 559 560 SetExpectationsForSaveLinkedProgram(kProgramId, &emulator); 561 cache_->SaveLinkedProgram(kProgramId, vertex_shader_, NULL, 562 fragment_shader_, NULL, NULL, 563 base::Bind(&MemoryProgramCacheTest::ShaderCacheCb, 564 base::Unretained(this))); 565 566 EXPECT_EQ(ProgramCache::LINK_SUCCEEDED, cache_->GetLinkedProgramStatus( 567 *vertex_shader_->deferred_compilation_source(), 568 NULL, 569 *fragment_shader_->deferred_compilation_source(), 570 NULL, 571 NULL)); 572 573 SetExpectationsForLoadLinkedProgram(kProgramId, &emulator); 574 575 fragment_shader_->UpdateSource("different!"); 576 EXPECT_EQ(ProgramCache::PROGRAM_LOAD_SUCCESS, cache_->LoadLinkedProgram( 577 kProgramId, 578 vertex_shader_, 579 NULL, 580 fragment_shader_, 581 NULL, 582 NULL, 583 base::Bind(&MemoryProgramCacheTest::ShaderCacheCb, 584 base::Unretained(this)))); 585} 586 587TEST_F(MemoryProgramCacheTest, OverwriteOnNewSave) { 588 const GLenum kFormat = 1; 589 const int kProgramId = 10; 590 const int kBinaryLength = 20; 591 char test_binary[kBinaryLength]; 592 for (int i = 0; i < kBinaryLength; ++i) { 593 test_binary[i] = i; 594 } 595 ProgramBinaryEmulator emulator(kBinaryLength, kFormat, test_binary); 596 597 SetExpectationsForSaveLinkedProgram(kProgramId, &emulator); 598 cache_->SaveLinkedProgram(kProgramId, vertex_shader_, NULL, 599 fragment_shader_, NULL, NULL, 600 base::Bind(&MemoryProgramCacheTest::ShaderCacheCb, 601 base::Unretained(this))); 602 603 604 char test_binary2[kBinaryLength]; 605 for (int i = 0; i < kBinaryLength; ++i) { 606 test_binary2[i] = (i*2) % 250; 607 } 608 ProgramBinaryEmulator emulator2(kBinaryLength, kFormat, test_binary2); 609 SetExpectationsForSaveLinkedProgram(kProgramId, &emulator2); 610 cache_->SaveLinkedProgram(kProgramId, vertex_shader_, NULL, 611 fragment_shader_, NULL, NULL, 612 base::Bind(&MemoryProgramCacheTest::ShaderCacheCb, 613 base::Unretained(this))); 614 615 SetExpectationsForLoadLinkedProgram(kProgramId, &emulator2); 616 EXPECT_EQ(ProgramCache::PROGRAM_LOAD_SUCCESS, cache_->LoadLinkedProgram( 617 kProgramId, 618 vertex_shader_, 619 NULL, 620 fragment_shader_, 621 NULL, 622 NULL, 623 base::Bind(&MemoryProgramCacheTest::ShaderCacheCb, 624 base::Unretained(this)))); 625} 626 627} // namespace gles2 628} // namespace gpu 629