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 18using ::testing::_; 19using ::testing::ElementsAreArray; 20using ::testing::Invoke; 21using ::testing::SetArgPointee; 22using ::testing::SetArrayArgument; 23 24namespace { 25typedef gpu::gles2::ShaderTranslator::VariableMap VariableMap; 26} // anonymous namespace 27 28namespace gpu { 29namespace gles2 { 30 31class ProgramBinaryEmulator { 32 public: 33 ProgramBinaryEmulator(GLsizei length, 34 GLenum format, 35 const char* binary) 36 : length_(length), 37 format_(format), 38 binary_(binary) { } 39 40 void GetProgramBinary(GLuint program, 41 GLsizei buffer_size, 42 GLsizei* length, 43 GLenum* format, 44 GLvoid* binary) { 45 if (length) { 46 *length = length_; 47 } 48 *format = format_; 49 memcpy(binary, binary_, length_); 50 } 51 52 void ProgramBinary(GLuint program, 53 GLenum format, 54 const GLvoid* binary, 55 GLsizei length) { 56 // format and length are verified by matcher 57 EXPECT_EQ(0, memcmp(binary_, binary, length)); 58 } 59 60 GLsizei length() const { return length_; } 61 GLenum format() const { return format_; } 62 const char* binary() const { return binary_; } 63 64 private: 65 GLsizei length_; 66 GLenum format_; 67 const char* binary_; 68}; 69 70class MemoryProgramCacheTest : public GpuServiceTest { 71 public: 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; 77 78 MemoryProgramCacheTest() 79 : cache_(new MemoryProgramCache(kCacheSizeBytes)), 80 vertex_shader_(NULL), 81 fragment_shader_(NULL), 82 shader_cache_count_(0) { } 83 virtual ~MemoryProgramCacheTest() { 84 shader_manager_.Destroy(false); 85 } 86 87 void ShaderCacheCb(const std::string& key, const std::string& shader) { 88 shader_cache_count_++; 89 shader_cache_shader_ = shader; 90 } 91 92 int32 shader_cache_count() { return shader_cache_count_; } 93 const std::string& shader_cache_shader() { return shader_cache_shader_; } 94 95 protected: 96 virtual void SetUp() { 97 GpuServiceTest::SetUp(); 98 99 vertex_shader_ = shader_manager_.CreateShader(kVertexShaderClientId, 100 kVertexShaderServiceId, 101 GL_VERTEX_SHADER); 102 fragment_shader_ = shader_manager_.CreateShader( 103 kFragmentShaderClientId, 104 kFragmentShaderServiceId, 105 GL_FRAGMENT_SHADER); 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; 116 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"); 126 127 vertex_shader_->set_source("bbbalsldkdkdkd"); 128 fragment_shader_->set_source("bbbal sldkdkdkas 134 ad"); 129 130 TestHelper::SetShaderStates( 131 gl_.get(), vertex_shader_, true, NULL, NULL, 132 &vertex_attrib_map, &vertex_uniform_map, &vertex_varying_map, 133 NULL); 134 TestHelper::SetShaderStates( 135 gl_.get(), fragment_shader_, true, NULL, NULL, 136 &fragment_attrib_map, &fragment_uniform_map, &fragment_varying_map, 137 NULL); 138 } 139 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)); 149 } 150 151 void SetExpectationsForLoadLinkedProgram( 152 const GLint program_id, 153 ProgramBinaryEmulator* emulator) const { 154 EXPECT_CALL(*gl_.get(), 155 ProgramBinary(program_id, 156 emulator->format(), 157 _, 158 emulator->length())) 159 .WillOnce(Invoke(emulator, &ProgramBinaryEmulator::ProgramBinary)); 160 EXPECT_CALL(*gl_.get(), 161 GetProgramiv(program_id, GL_LINK_STATUS, _)) 162 .WillOnce(SetArgPointee<2>(GL_TRUE)); 163 } 164 165 void SetExpectationsForLoadLinkedProgramFailure( 166 const GLint program_id, 167 ProgramBinaryEmulator* emulator) const { 168 EXPECT_CALL(*gl_.get(), 169 ProgramBinary(program_id, 170 emulator->format(), 171 _, 172 emulator->length())) 173 .WillOnce(Invoke(emulator, &ProgramBinaryEmulator::ProgramBinary)); 174 EXPECT_CALL(*gl_.get(), 175 GetProgramiv(program_id, GL_LINK_STATUS, _)) 176 .WillOnce(SetArgPointee<2>(GL_FALSE)); 177 } 178 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_; 185}; 186 187TEST_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) { 193 test_binary[i] = i; 194 } 195 ProgramBinaryEmulator emulator(kBinaryLength, kFormat, test_binary); 196 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))); 202 203 EXPECT_EQ(ProgramCache::LINK_SUCCEEDED, cache_->GetLinkedProgramStatus( 204 vertex_shader_->signature_source(), 205 NULL, 206 fragment_shader_->signature_source(), 207 NULL, 208 NULL)); 209 EXPECT_EQ(1, shader_cache_count()); 210} 211 212TEST_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) { 218 test_binary[i] = i; 219 } 220 ProgramBinaryEmulator emulator(kBinaryLength, kFormat, test_binary); 221 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))); 227 228 EXPECT_EQ(ProgramCache::LINK_SUCCEEDED, cache_->GetLinkedProgramStatus( 229 vertex_shader_->signature_source(), 230 NULL, 231 fragment_shader_->signature_source(), 232 NULL, 233 NULL)); 234 EXPECT_EQ(1, shader_cache_count()); 235 236 cache_->Clear(); 237 238 cache_->LoadProgram(shader_cache_shader()); 239 EXPECT_EQ(ProgramCache::LINK_SUCCEEDED, cache_->GetLinkedProgramStatus( 240 vertex_shader_->signature_source(), 241 NULL, 242 fragment_shader_->signature_source(), 243 NULL, 244 NULL)); 245} 246 247TEST_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) { 253 test_binary[i] = i; 254 } 255 ProgramBinaryEmulator emulator(kBinaryLength, kFormat, test_binary); 256 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()); 263 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(); 270 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()); 277 278 SetExpectationsForLoadLinkedProgram(kProgramId, &emulator); 279 280 EXPECT_EQ(ProgramCache::PROGRAM_LOAD_SUCCESS, cache_->LoadLinkedProgram( 281 kProgramId, 282 vertex_shader_, 283 NULL, 284 fragment_shader_, 285 NULL, 286 NULL, 287 base::Bind(&MemoryProgramCacheTest::ShaderCacheCb, 288 base::Unretained(this)))); 289 290 // apparently the hash_map implementation on android doesn't have the 291 // equality operator 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()); 299#endif 300} 301 302TEST_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) { 308 test_binary[i] = i; 309 } 310 ProgramBinaryEmulator emulator(kBinaryLength, kFormat, test_binary); 311 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()); 318 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(); 325 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()); 332 333 SetExpectationsForLoadLinkedProgram(kProgramId, &emulator); 334 335 cache_->Clear(); 336 cache_->LoadProgram(shader_cache_shader()); 337 338 EXPECT_EQ(ProgramCache::PROGRAM_LOAD_SUCCESS, cache_->LoadLinkedProgram( 339 kProgramId, 340 vertex_shader_, 341 NULL, 342 fragment_shader_, 343 NULL, 344 NULL, 345 base::Bind(&MemoryProgramCacheTest::ShaderCacheCb, 346 base::Unretained(this)))); 347 348 // apparently the hash_map implementation on android doesn't have the 349 // equality operator 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()); 357#endif 358} 359 360TEST_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) { 366 test_binary[i] = i; 367 } 368 ProgramBinaryEmulator emulator(kBinaryLength, kFormat, test_binary); 369 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))); 375 376 SetExpectationsForLoadLinkedProgramFailure(kProgramId, &emulator); 377 EXPECT_EQ(ProgramCache::PROGRAM_LOAD_FAILURE, cache_->LoadLinkedProgram( 378 kProgramId, 379 vertex_shader_, 380 NULL, 381 fragment_shader_, 382 NULL, 383 NULL, 384 base::Bind(&MemoryProgramCacheTest::ShaderCacheCb, 385 base::Unretained(this)))); 386} 387 388TEST_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) { 394 test_binary[i] = i; 395 } 396 ProgramBinaryEmulator emulator(kBinaryLength, kFormat, test_binary); 397 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))); 403 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( 408 kProgramId, 409 vertex_shader_, 410 NULL, 411 fragment_shader_, 412 NULL, 413 NULL, 414 base::Bind(&MemoryProgramCacheTest::ShaderCacheCb, 415 base::Unretained(this)))); 416 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( 422 kProgramId, 423 vertex_shader_, 424 NULL, 425 fragment_shader_, 426 NULL, 427 NULL, 428 base::Bind(&MemoryProgramCacheTest::ShaderCacheCb, 429 base::Unretained(this)))); 430} 431 432TEST_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) { 438 test_binary[i] = i; 439 } 440 ProgramBinaryEmulator emulator(kBinaryLength, kFormat, test_binary); 441 442 SetExpectationsForSaveLinkedProgram(kProgramId, &emulator); 443 ProgramCache::LocationMap binding_map; 444 binding_map["test"] = 512; 445 cache_->SaveLinkedProgram(kProgramId, 446 vertex_shader_, 447 NULL, 448 fragment_shader_, 449 NULL, 450 &binding_map, 451 base::Bind(&MemoryProgramCacheTest::ShaderCacheCb, 452 base::Unretained(this))); 453 454 binding_map["different!"] = 59; 455 EXPECT_EQ(ProgramCache::PROGRAM_LOAD_FAILURE, cache_->LoadLinkedProgram( 456 kProgramId, 457 vertex_shader_, 458 NULL, 459 fragment_shader_, 460 NULL, 461 &binding_map, 462 base::Bind(&MemoryProgramCacheTest::ShaderCacheCb, 463 base::Unretained(this)))); 464 EXPECT_EQ(ProgramCache::PROGRAM_LOAD_FAILURE, cache_->LoadLinkedProgram( 465 kProgramId, 466 vertex_shader_, 467 NULL, 468 fragment_shader_, 469 NULL, 470 NULL, 471 base::Bind(&MemoryProgramCacheTest::ShaderCacheCb, 472 base::Unretained(this)))); 473} 474 475TEST_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) { 481 test_binary[i] = i; 482 } 483 ProgramBinaryEmulator emulator1(kBinaryLength, kFormat, test_binary); 484 485 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))); 491 492 const int kEvictingProgramId = 11; 493 const GLuint kEvictingBinaryLength = kCacheSizeBytes - kBinaryLength + 1; 494 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); 499 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; 504 } 505 ProgramBinaryEmulator emulator2(kEvictingBinaryLength, 506 kFormat, 507 bigTestBinary.get()); 508 509 SetExpectationsForSaveLinkedProgram(kEvictingProgramId, &emulator2); 510 cache_->SaveLinkedProgram(kEvictingProgramId, 511 vertex_shader_, 512 NULL, 513 fragment_shader_, 514 NULL, 515 NULL, 516 base::Bind(&MemoryProgramCacheTest::ShaderCacheCb, 517 base::Unretained(this))); 518 519 EXPECT_EQ(ProgramCache::LINK_SUCCEEDED, cache_->GetLinkedProgramStatus( 520 vertex_shader_->signature_source(), 521 NULL, 522 fragment_shader_->signature_source(), 523 NULL, 524 NULL)); 525 EXPECT_EQ(ProgramCache::LINK_UNKNOWN, cache_->GetLinkedProgramStatus( 526 old_source, 527 NULL, 528 fragment_shader_->signature_source(), 529 NULL, 530 NULL)); 531} 532 533TEST_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) { 539 test_binary[i] = i; 540 } 541 ProgramBinaryEmulator emulator1(kBinaryLength, kFormat, test_binary); 542 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))); 549 550 EXPECT_EQ(ProgramCache::LINK_SUCCEEDED, cache_->GetLinkedProgramStatus( 551 vertex_shader_->signature_source(), 552 NULL, 553 fragment_shader_->signature_source(), 554 NULL, 555 NULL)); 556} 557 558TEST_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) { 564 test_binary[i] = i; 565 } 566 ProgramBinaryEmulator emulator(kBinaryLength, kFormat, test_binary); 567 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))); 573 574 EXPECT_EQ(ProgramCache::LINK_SUCCEEDED, cache_->GetLinkedProgramStatus( 575 vertex_shader_->signature_source(), 576 NULL, 577 fragment_shader_->signature_source(), 578 NULL, 579 NULL)); 580 581 SetExpectationsForLoadLinkedProgram(kProgramId, &emulator); 582 583 fragment_shader_->set_source("different!"); 584 EXPECT_EQ(ProgramCache::PROGRAM_LOAD_SUCCESS, cache_->LoadLinkedProgram( 585 kProgramId, 586 vertex_shader_, 587 NULL, 588 fragment_shader_, 589 NULL, 590 NULL, 591 base::Bind(&MemoryProgramCacheTest::ShaderCacheCb, 592 base::Unretained(this)))); 593} 594 595TEST_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) { 601 test_binary[i] = i; 602 } 603 ProgramBinaryEmulator emulator(kBinaryLength, kFormat, test_binary); 604 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))); 610 611 612 char test_binary2[kBinaryLength]; 613 for (int i = 0; i < kBinaryLength; ++i) { 614 test_binary2[i] = (i*2) % 250; 615 } 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))); 622 623 SetExpectationsForLoadLinkedProgram(kProgramId, &emulator2); 624 EXPECT_EQ(ProgramCache::PROGRAM_LOAD_SUCCESS, cache_->LoadLinkedProgram( 625 kProgramId, 626 vertex_shader_, 627 NULL, 628 fragment_shader_, 629 NULL, 630 NULL, 631 base::Bind(&MemoryProgramCacheTest::ShaderCacheCb, 632 base::Unretained(this)))); 633} 634 635} // namespace gles2 636} // namespace gpu 637