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 "content/common/gpu/gpu_memory_manager.h" 6#include "content/common/gpu/gpu_memory_manager_client.h" 7#include "content/common/gpu/gpu_memory_tracking.h" 8#include "gpu/command_buffer/common/gpu_memory_allocation.h" 9#include "ui/gfx/size_conversions.h" 10 11#include "testing/gtest/include/gtest/gtest.h" 12 13using gpu::MemoryAllocation; 14using gpu::ManagedMemoryStats; 15 16#if defined(COMPILER_GCC) 17namespace BASE_HASH_NAMESPACE { 18template<> 19struct hash<content::GpuMemoryManagerClient*> { 20 uint64 operator()(content::GpuMemoryManagerClient* ptr) const { 21 return hash<uint64>()(reinterpret_cast<uint64>(ptr)); 22 } 23}; 24} // namespace BASE_HASH_NAMESPACE 25#endif // COMPILER 26 27class FakeMemoryTracker : public gpu::gles2::MemoryTracker { 28 public: 29 virtual void TrackMemoryAllocatedChange( 30 size_t /* old_size */, 31 size_t /* new_size */, 32 gpu::gles2::MemoryTracker::Pool /* pool */) OVERRIDE { 33 } 34 virtual bool EnsureGPUMemoryAvailable(size_t /* size_needed */) OVERRIDE { 35 return true; 36 } 37 private: 38 virtual ~FakeMemoryTracker() { 39 } 40}; 41 42namespace content { 43 44// This class is used to collect all stub assignments during a 45// Manage() call. 46class ClientAssignmentCollector { 47 public: 48 struct ClientMemoryStat { 49 MemoryAllocation allocation; 50 }; 51 typedef base::hash_map<GpuMemoryManagerClient*, ClientMemoryStat> 52 ClientMemoryStatMap; 53 54 static const ClientMemoryStatMap& GetClientStatsForLastManage() { 55 return client_memory_stats_for_last_manage_; 56 } 57 static void ClearAllStats() { 58 client_memory_stats_for_last_manage_.clear(); 59 } 60 static void AddClientStat(GpuMemoryManagerClient* client, 61 const MemoryAllocation& allocation) { 62 DCHECK(!client_memory_stats_for_last_manage_.count(client)); 63 client_memory_stats_for_last_manage_[client].allocation = allocation; 64 } 65 66 private: 67 static ClientMemoryStatMap client_memory_stats_for_last_manage_; 68}; 69 70ClientAssignmentCollector::ClientMemoryStatMap 71 ClientAssignmentCollector::client_memory_stats_for_last_manage_; 72 73class FakeClient : public GpuMemoryManagerClient { 74 public: 75 GpuMemoryManager* memmgr_; 76 bool suggest_have_frontbuffer_; 77 MemoryAllocation allocation_; 78 uint64 total_gpu_memory_; 79 gfx::Size surface_size_; 80 GpuMemoryManagerClient* share_group_; 81 scoped_refptr<gpu::gles2::MemoryTracker> memory_tracker_; 82 scoped_ptr<GpuMemoryTrackingGroup> tracking_group_; 83 scoped_ptr<GpuMemoryManagerClientState> client_state_; 84 85 // This will create a client with no surface 86 FakeClient(GpuMemoryManager* memmgr, GpuMemoryManagerClient* share_group) 87 : memmgr_(memmgr), 88 suggest_have_frontbuffer_(false), 89 total_gpu_memory_(0), 90 share_group_(share_group), 91 memory_tracker_(NULL) { 92 if (!share_group_) { 93 memory_tracker_ = new FakeMemoryTracker(); 94 tracking_group_.reset( 95 memmgr_->CreateTrackingGroup(0, memory_tracker_.get())); 96 } 97 client_state_.reset(memmgr_->CreateClientState(this, false, true)); 98 } 99 100 // This will create a client with a surface 101 FakeClient(GpuMemoryManager* memmgr, int32 surface_id, bool visible) 102 : memmgr_(memmgr), 103 suggest_have_frontbuffer_(false), 104 total_gpu_memory_(0), 105 share_group_(NULL), 106 memory_tracker_(NULL) { 107 memory_tracker_ = new FakeMemoryTracker(); 108 tracking_group_.reset( 109 memmgr_->CreateTrackingGroup(0, memory_tracker_.get())); 110 client_state_.reset( 111 memmgr_->CreateClientState(this, surface_id != 0, visible)); 112 } 113 114 virtual ~FakeClient() { 115 client_state_.reset(); 116 tracking_group_.reset(); 117 memory_tracker_ = NULL; 118 } 119 120 virtual void SetMemoryAllocation(const MemoryAllocation& alloc) OVERRIDE { 121 allocation_ = alloc; 122 ClientAssignmentCollector::AddClientStat(this, alloc); 123 } 124 125 virtual void SuggestHaveFrontBuffer(bool suggest_have_frontbuffer) OVERRIDE { 126 suggest_have_frontbuffer_ = suggest_have_frontbuffer; 127 } 128 129 virtual bool GetTotalGpuMemory(uint64* bytes) OVERRIDE { 130 if (total_gpu_memory_) { 131 *bytes = total_gpu_memory_; 132 return true; 133 } 134 return false; 135 } 136 void SetTotalGpuMemory(uint64 bytes) { total_gpu_memory_ = bytes; } 137 138 virtual gpu::gles2::MemoryTracker* GetMemoryTracker() const OVERRIDE { 139 if (share_group_) 140 return share_group_->GetMemoryTracker(); 141 return memory_tracker_.get(); 142 } 143 144 virtual gfx::Size GetSurfaceSize() const OVERRIDE { 145 return surface_size_; 146 } 147 void SetSurfaceSize(gfx::Size size) { surface_size_ = size; } 148 149 void SetVisible(bool visible) { 150 client_state_->SetVisible(visible); 151 } 152 153 void SetManagedMemoryStats(const ManagedMemoryStats& stats) { 154 client_state_->SetManagedMemoryStats(stats); 155 } 156 157 uint64 BytesWhenVisible() const { 158 return allocation_.bytes_limit_when_visible; 159 } 160}; 161 162class GpuMemoryManagerTest : public testing::Test { 163 protected: 164 static const uint64 kFrontbufferLimitForTest = 3; 165 166 GpuMemoryManagerTest() 167 : memmgr_(0, kFrontbufferLimitForTest) { 168 memmgr_.TestingDisableScheduleManage(); 169 } 170 171 virtual void SetUp() { 172 } 173 174 static int32 GenerateUniqueSurfaceId() { 175 static int32 surface_id_ = 1; 176 return surface_id_++; 177 } 178 179 bool IsAllocationForegroundForSurfaceYes( 180 const MemoryAllocation& alloc) { 181 return true; 182 } 183 bool IsAllocationBackgroundForSurfaceYes( 184 const MemoryAllocation& alloc) { 185 return true; 186 } 187 bool IsAllocationHibernatedForSurfaceYes( 188 const MemoryAllocation& alloc) { 189 return true; 190 } 191 bool IsAllocationForegroundForSurfaceNo( 192 const MemoryAllocation& alloc) { 193 return alloc.bytes_limit_when_visible == 194 GetMinimumClientAllocation(); 195 } 196 bool IsAllocationBackgroundForSurfaceNo( 197 const MemoryAllocation& alloc) { 198 return alloc.bytes_limit_when_visible == 199 GetMinimumClientAllocation(); 200 } 201 bool IsAllocationHibernatedForSurfaceNo( 202 const MemoryAllocation& alloc) { 203 return alloc.bytes_limit_when_visible == 0; 204 } 205 206 void Manage() { 207 ClientAssignmentCollector::ClearAllStats(); 208 memmgr_.Manage(); 209 } 210 211 uint64 CalcAvailableFromGpuTotal(uint64 bytes) { 212 return GpuMemoryManager::CalcAvailableFromGpuTotal(bytes); 213 } 214 215 uint64 CalcAvailableClamped(uint64 bytes) { 216 bytes = std::max(bytes, memmgr_.GetDefaultAvailableGpuMemory()); 217 bytes = std::min(bytes, memmgr_.GetMaximumTotalGpuMemory()); 218 return bytes; 219 } 220 221 uint64 GetAvailableGpuMemory() { 222 return memmgr_.GetAvailableGpuMemory(); 223 } 224 225 uint64 GetMaximumClientAllocation() { 226 return memmgr_.GetMaximumClientAllocation(); 227 } 228 229 uint64 GetMinimumClientAllocation() { 230 return memmgr_.GetMinimumClientAllocation(); 231 } 232 233 void SetClientStats( 234 FakeClient* client, 235 uint64 required, 236 uint64 nicetohave) { 237 client->SetManagedMemoryStats( 238 ManagedMemoryStats(required, nicetohave, 0, false)); 239 } 240 241 GpuMemoryManager memmgr_; 242}; 243 244// Test GpuMemoryManager::Manage basic functionality. 245// Expect memory allocation to set suggest_have_frontbuffer/backbuffer 246// according to visibility and last used time for stubs with surface. 247// Expect memory allocation to be shared according to share groups for stubs 248// without a surface. 249TEST_F(GpuMemoryManagerTest, TestManageBasicFunctionality) { 250 // Test stubs with surface. 251 FakeClient stub1(&memmgr_, GenerateUniqueSurfaceId(), true), 252 stub2(&memmgr_, GenerateUniqueSurfaceId(), false); 253 254 Manage(); 255 EXPECT_TRUE(IsAllocationForegroundForSurfaceYes(stub1.allocation_)); 256 EXPECT_TRUE(IsAllocationBackgroundForSurfaceYes(stub2.allocation_)); 257 258 // Test stubs without surface, with share group of 1 stub. 259 FakeClient stub3(&memmgr_, &stub1), stub4(&memmgr_, &stub2); 260 261 Manage(); 262 EXPECT_TRUE(IsAllocationForegroundForSurfaceYes(stub1.allocation_)); 263 EXPECT_TRUE(IsAllocationBackgroundForSurfaceYes(stub2.allocation_)); 264 EXPECT_TRUE(IsAllocationForegroundForSurfaceNo(stub3.allocation_)); 265 EXPECT_TRUE(IsAllocationBackgroundForSurfaceNo(stub4.allocation_)); 266 267 // Test stub without surface, with share group of multiple stubs. 268 FakeClient stub5(&memmgr_ , &stub2); 269 270 Manage(); 271 EXPECT_TRUE(IsAllocationForegroundForSurfaceNo(stub4.allocation_)); 272} 273 274// Test GpuMemoryManager::Manage functionality: changing visibility. 275// Expect memory allocation to set suggest_have_frontbuffer/backbuffer 276// according to visibility and last used time for stubs with surface. 277// Expect memory allocation to be shared according to share groups for stubs 278// without a surface. 279TEST_F(GpuMemoryManagerTest, TestManageChangingVisibility) { 280 FakeClient stub1(&memmgr_, GenerateUniqueSurfaceId(), true), 281 stub2(&memmgr_, GenerateUniqueSurfaceId(), false); 282 283 FakeClient stub3(&memmgr_, &stub1), stub4(&memmgr_, &stub2); 284 FakeClient stub5(&memmgr_ , &stub2); 285 286 Manage(); 287 EXPECT_TRUE(IsAllocationForegroundForSurfaceYes(stub1.allocation_)); 288 EXPECT_TRUE(IsAllocationBackgroundForSurfaceYes(stub2.allocation_)); 289 EXPECT_TRUE(IsAllocationForegroundForSurfaceNo(stub3.allocation_)); 290 EXPECT_TRUE(IsAllocationBackgroundForSurfaceNo(stub4.allocation_)); 291 EXPECT_TRUE(IsAllocationForegroundForSurfaceNo(stub5.allocation_)); 292 293 stub1.SetVisible(false); 294 stub2.SetVisible(true); 295 296 Manage(); 297 EXPECT_TRUE(IsAllocationBackgroundForSurfaceYes(stub1.allocation_)); 298 EXPECT_TRUE(IsAllocationForegroundForSurfaceYes(stub2.allocation_)); 299 EXPECT_TRUE(IsAllocationBackgroundForSurfaceNo(stub3.allocation_)); 300 EXPECT_TRUE(IsAllocationForegroundForSurfaceNo(stub4.allocation_)); 301 EXPECT_TRUE(IsAllocationForegroundForSurfaceNo(stub5.allocation_)); 302} 303 304// Test GpuMemoryManager::Manage functionality: Test more than threshold number 305// of visible stubs. 306// Expect all allocations to continue to have frontbuffer. 307TEST_F(GpuMemoryManagerTest, TestManageManyVisibleStubs) { 308 FakeClient stub1(&memmgr_, GenerateUniqueSurfaceId(), true), 309 stub2(&memmgr_, GenerateUniqueSurfaceId(), true), 310 stub3(&memmgr_, GenerateUniqueSurfaceId(), true), 311 stub4(&memmgr_, GenerateUniqueSurfaceId(), true); 312 313 FakeClient stub5(&memmgr_ , &stub1), stub6(&memmgr_ , &stub2); 314 FakeClient stub7(&memmgr_ , &stub2); 315 316 Manage(); 317 EXPECT_TRUE(IsAllocationForegroundForSurfaceYes(stub1.allocation_)); 318 EXPECT_TRUE(IsAllocationForegroundForSurfaceYes(stub2.allocation_)); 319 EXPECT_TRUE(IsAllocationForegroundForSurfaceYes(stub3.allocation_)); 320 EXPECT_TRUE(IsAllocationForegroundForSurfaceYes(stub4.allocation_)); 321 EXPECT_TRUE(IsAllocationForegroundForSurfaceNo(stub5.allocation_)); 322 EXPECT_TRUE(IsAllocationForegroundForSurfaceNo(stub6.allocation_)); 323 EXPECT_TRUE(IsAllocationForegroundForSurfaceNo(stub7.allocation_)); 324} 325 326// Test GpuMemoryManager::Manage functionality: Test more than threshold number 327// of not visible stubs. 328// Expect the stubs surpassing the threshold to not have a backbuffer. 329TEST_F(GpuMemoryManagerTest, TestManageManyNotVisibleStubs) { 330 FakeClient stub1(&memmgr_, GenerateUniqueSurfaceId(), true), 331 stub2(&memmgr_, GenerateUniqueSurfaceId(), true), 332 stub3(&memmgr_, GenerateUniqueSurfaceId(), true), 333 stub4(&memmgr_, GenerateUniqueSurfaceId(), true); 334 stub4.SetVisible(false); 335 stub3.SetVisible(false); 336 stub2.SetVisible(false); 337 stub1.SetVisible(false); 338 339 FakeClient stub5(&memmgr_ , &stub1), stub6(&memmgr_ , &stub4); 340 FakeClient stub7(&memmgr_ , &stub1); 341 342 Manage(); 343 EXPECT_TRUE(IsAllocationBackgroundForSurfaceYes(stub1.allocation_)); 344 EXPECT_TRUE(IsAllocationBackgroundForSurfaceYes(stub2.allocation_)); 345 EXPECT_TRUE(IsAllocationBackgroundForSurfaceYes(stub3.allocation_)); 346 EXPECT_TRUE(IsAllocationHibernatedForSurfaceYes(stub4.allocation_)); 347 EXPECT_TRUE(IsAllocationBackgroundForSurfaceNo(stub5.allocation_)); 348 EXPECT_TRUE(IsAllocationHibernatedForSurfaceNo(stub6.allocation_)); 349 EXPECT_TRUE(IsAllocationBackgroundForSurfaceNo(stub7.allocation_)); 350} 351 352// Test GpuMemoryManager::Manage functionality: Test changing the last used 353// time of stubs when doing so causes change in which stubs surpass threshold. 354// Expect frontbuffer to be dropped for the older stub. 355TEST_F(GpuMemoryManagerTest, TestManageChangingLastUsedTime) { 356 FakeClient stub1(&memmgr_, GenerateUniqueSurfaceId(), true), 357 stub2(&memmgr_, GenerateUniqueSurfaceId(), true), 358 stub3(&memmgr_, GenerateUniqueSurfaceId(), true), 359 stub4(&memmgr_, GenerateUniqueSurfaceId(), true); 360 361 FakeClient stub5(&memmgr_ , &stub3), stub6(&memmgr_ , &stub4); 362 FakeClient stub7(&memmgr_ , &stub3); 363 364 // Make stub4 be the least-recently-used client 365 stub4.SetVisible(false); 366 stub3.SetVisible(false); 367 stub2.SetVisible(false); 368 stub1.SetVisible(false); 369 370 Manage(); 371 EXPECT_TRUE(IsAllocationBackgroundForSurfaceYes(stub1.allocation_)); 372 EXPECT_TRUE(IsAllocationBackgroundForSurfaceYes(stub2.allocation_)); 373 EXPECT_TRUE(IsAllocationBackgroundForSurfaceYes(stub3.allocation_)); 374 EXPECT_TRUE(IsAllocationHibernatedForSurfaceYes(stub4.allocation_)); 375 EXPECT_TRUE(IsAllocationBackgroundForSurfaceNo(stub5.allocation_)); 376 EXPECT_TRUE(IsAllocationHibernatedForSurfaceNo(stub6.allocation_)); 377 EXPECT_TRUE(IsAllocationBackgroundForSurfaceNo(stub7.allocation_)); 378 379 // Make stub3 become the least-recently-used client. 380 stub2.SetVisible(true); 381 stub2.SetVisible(false); 382 stub4.SetVisible(true); 383 stub4.SetVisible(false); 384 385 Manage(); 386 EXPECT_TRUE(IsAllocationBackgroundForSurfaceYes(stub1.allocation_)); 387 EXPECT_TRUE(IsAllocationBackgroundForSurfaceYes(stub2.allocation_)); 388 EXPECT_TRUE(IsAllocationHibernatedForSurfaceYes(stub3.allocation_)); 389 EXPECT_TRUE(IsAllocationBackgroundForSurfaceYes(stub4.allocation_)); 390 EXPECT_TRUE(IsAllocationHibernatedForSurfaceNo(stub5.allocation_)); 391 EXPECT_TRUE(IsAllocationBackgroundForSurfaceNo(stub6.allocation_)); 392 EXPECT_TRUE(IsAllocationHibernatedForSurfaceNo(stub7.allocation_)); 393} 394 395// Test GpuMemoryManager::Manage functionality: Test changing importance of 396// enough stubs so that every stub in share group crosses threshold. 397// Expect memory allocation of the stubs without surface to share memory 398// allocation with the most visible stub in share group. 399TEST_F(GpuMemoryManagerTest, TestManageChangingImportanceShareGroup) { 400 FakeClient stub_ignore_a(&memmgr_, GenerateUniqueSurfaceId(), true), 401 stub_ignore_b(&memmgr_, GenerateUniqueSurfaceId(), false), 402 stub_ignore_c(&memmgr_, GenerateUniqueSurfaceId(), false); 403 FakeClient stub1(&memmgr_, GenerateUniqueSurfaceId(), false), 404 stub2(&memmgr_, GenerateUniqueSurfaceId(), false); 405 406 FakeClient stub3(&memmgr_, &stub2), stub4(&memmgr_, &stub2); 407 408 // stub1 and stub2 keep their non-hibernated state because they're 409 // either visible or the 2 most recently used clients (through the 410 // first three checks). 411 stub1.SetVisible(true); 412 stub2.SetVisible(true); 413 Manage(); 414 EXPECT_TRUE(IsAllocationForegroundForSurfaceYes(stub1.allocation_)); 415 EXPECT_TRUE(IsAllocationForegroundForSurfaceYes(stub2.allocation_)); 416 EXPECT_TRUE(IsAllocationForegroundForSurfaceNo(stub3.allocation_)); 417 EXPECT_TRUE(IsAllocationForegroundForSurfaceNo(stub4.allocation_)); 418 419 stub1.SetVisible(false); 420 Manage(); 421 EXPECT_TRUE(IsAllocationBackgroundForSurfaceYes(stub1.allocation_)); 422 EXPECT_TRUE(IsAllocationForegroundForSurfaceYes(stub2.allocation_)); 423 EXPECT_TRUE(IsAllocationBackgroundForSurfaceNo(stub3.allocation_)); 424 EXPECT_TRUE(IsAllocationForegroundForSurfaceNo(stub4.allocation_)); 425 426 stub2.SetVisible(false); 427 Manage(); 428 EXPECT_TRUE(IsAllocationBackgroundForSurfaceYes(stub1.allocation_)); 429 EXPECT_TRUE(IsAllocationBackgroundForSurfaceYes(stub2.allocation_)); 430 EXPECT_TRUE(IsAllocationBackgroundForSurfaceNo(stub3.allocation_)); 431 EXPECT_TRUE(IsAllocationBackgroundForSurfaceNo(stub4.allocation_)); 432 433 // stub_ignore_b will cause stub1 to become hibernated (because 434 // stub_ignore_a, stub_ignore_b, and stub2 are all non-hibernated and more 435 // important). 436 stub_ignore_b.SetVisible(true); 437 stub_ignore_b.SetVisible(false); 438 Manage(); 439 EXPECT_TRUE(IsAllocationHibernatedForSurfaceYes(stub1.allocation_)); 440 EXPECT_TRUE(IsAllocationBackgroundForSurfaceYes(stub2.allocation_)); 441 EXPECT_TRUE(IsAllocationBackgroundForSurfaceNo(stub3.allocation_)); 442 EXPECT_TRUE(IsAllocationBackgroundForSurfaceNo(stub4.allocation_)); 443 444 // stub_ignore_c will cause stub2 to become hibernated (because 445 // stub_ignore_a, stub_ignore_b, and stub_ignore_c are all non-hibernated 446 // and more important). 447 stub_ignore_c.SetVisible(true); 448 stub_ignore_c.SetVisible(false); 449 Manage(); 450 EXPECT_TRUE(IsAllocationHibernatedForSurfaceYes(stub1.allocation_)); 451 EXPECT_TRUE(IsAllocationHibernatedForSurfaceYes(stub2.allocation_)); 452 EXPECT_TRUE(IsAllocationHibernatedForSurfaceNo(stub3.allocation_)); 453 EXPECT_TRUE(IsAllocationHibernatedForSurfaceNo(stub4.allocation_)); 454} 455 456// Test GpuMemoryManager::UpdateAvailableGpuMemory functionality 457TEST_F(GpuMemoryManagerTest, TestUpdateAvailableGpuMemory) { 458 FakeClient stub1(&memmgr_, GenerateUniqueSurfaceId(), true), 459 stub2(&memmgr_, GenerateUniqueSurfaceId(), false), 460 stub3(&memmgr_, GenerateUniqueSurfaceId(), true), 461 stub4(&memmgr_, GenerateUniqueSurfaceId(), false); 462 // We take the lowest GPU's total memory as the limit 463 uint64 expected = 400 * 1024 * 1024; 464 stub1.SetTotalGpuMemory(expected); // GPU Memory 465 stub2.SetTotalGpuMemory(expected - 1024 * 1024); // Smaller but not visible. 466 stub3.SetTotalGpuMemory(expected + 1024 * 1024); // Visible but larger. 467 stub4.SetTotalGpuMemory(expected + 1024 * 1024); // Not visible and larger. 468 Manage(); 469 uint64 bytes_expected = CalcAvailableFromGpuTotal(expected); 470 EXPECT_EQ(GetAvailableGpuMemory(), CalcAvailableClamped(bytes_expected)); 471} 472 473// Test GpuMemoryManager Stub Memory Stats functionality: 474// Creates various surface/non-surface stubs and switches stub visibility and 475// tests to see that stats data structure values are correct. 476TEST_F(GpuMemoryManagerTest, StubMemoryStatsForLastManageTests) { 477 ClientAssignmentCollector::ClientMemoryStatMap stats; 478 479 Manage(); 480 stats = ClientAssignmentCollector::GetClientStatsForLastManage(); 481 EXPECT_EQ(stats.size(), 0ul); 482 483 FakeClient stub1(&memmgr_, GenerateUniqueSurfaceId(), true); 484 Manage(); 485 stats = ClientAssignmentCollector::GetClientStatsForLastManage(); 486 uint64 stub1allocation1 = 487 stats[&stub1].allocation.bytes_limit_when_visible; 488 489 EXPECT_EQ(stats.size(), 1ul); 490 EXPECT_GT(stub1allocation1, 0ul); 491 492 FakeClient stub2(&memmgr_, &stub1); 493 Manage(); 494 stats = ClientAssignmentCollector::GetClientStatsForLastManage(); 495 EXPECT_EQ(stats.count(&stub1), 1ul); 496 uint64 stub1allocation2 = 497 stats[&stub1].allocation.bytes_limit_when_visible; 498 EXPECT_EQ(stats.count(&stub2), 1ul); 499 uint64 stub2allocation2 = 500 stats[&stub2].allocation.bytes_limit_when_visible; 501 502 EXPECT_EQ(stats.size(), 2ul); 503 EXPECT_GT(stub1allocation2, 0ul); 504 EXPECT_GT(stub2allocation2, 0ul); 505 if (stub1allocation2 != GetMaximumClientAllocation()) 506 EXPECT_LT(stub1allocation2, stub1allocation1); 507 508 FakeClient stub3(&memmgr_, GenerateUniqueSurfaceId(), true); 509 Manage(); 510 stats = ClientAssignmentCollector::GetClientStatsForLastManage(); 511 uint64 stub1allocation3 = 512 stats[&stub1].allocation.bytes_limit_when_visible; 513 uint64 stub2allocation3 = 514 stats[&stub2].allocation.bytes_limit_when_visible; 515 uint64 stub3allocation3 = 516 stats[&stub3].allocation.bytes_limit_when_visible; 517 518 EXPECT_EQ(stats.size(), 3ul); 519 EXPECT_GT(stub1allocation3, 0ul); 520 EXPECT_GT(stub2allocation3, 0ul); 521 EXPECT_GT(stub3allocation3, 0ul); 522 if (stub1allocation3 != GetMaximumClientAllocation()) 523 EXPECT_LT(stub1allocation3, stub1allocation2); 524 525 stub1.SetVisible(false); 526 527 Manage(); 528 stats = ClientAssignmentCollector::GetClientStatsForLastManage(); 529 uint64 stub1allocation4 = 530 stats[&stub1].allocation.bytes_limit_when_visible; 531 uint64 stub2allocation4 = 532 stats[&stub2].allocation.bytes_limit_when_visible; 533 uint64 stub3allocation4 = 534 stats[&stub3].allocation.bytes_limit_when_visible; 535 536 EXPECT_EQ(stats.size(), 3ul); 537 EXPECT_GT(stub1allocation4, 0ul); 538 EXPECT_GE(stub2allocation4, 0ul); 539 EXPECT_GT(stub3allocation4, 0ul); 540 if (stub3allocation3 != GetMaximumClientAllocation()) 541 EXPECT_GT(stub3allocation4, stub3allocation3); 542} 543 544// Test tracking of unmanaged (e.g, WebGL) memory. 545TEST_F(GpuMemoryManagerTest, UnmanagedTracking) { 546 // Set memory manager constants for this test 547 memmgr_.TestingSetAvailableGpuMemory(64); 548 memmgr_.TestingSetMinimumClientAllocation(8); 549 memmgr_.TestingSetUnmanagedLimitStep(16); 550 551 FakeClient stub1(&memmgr_, GenerateUniqueSurfaceId(), true); 552 553 // Expect that the one stub get its nicetohave level. 554 SetClientStats(&stub1, 16, 32); 555 Manage(); 556 EXPECT_GE(stub1.BytesWhenVisible(), 32u); 557 558 // Now allocate some unmanaged memory and make sure the amount 559 // goes down. 560 memmgr_.TrackMemoryAllocatedChange( 561 stub1.tracking_group_.get(), 562 0, 563 48, 564 gpu::gles2::MemoryTracker::kUnmanaged); 565 Manage(); 566 EXPECT_LT(stub1.BytesWhenVisible(), 24u); 567 568 // Now allocate the entire FB worth of unmanaged memory, and 569 // make sure that we stay stuck at the minimum tab allocation. 570 memmgr_.TrackMemoryAllocatedChange( 571 stub1.tracking_group_.get(), 572 48, 573 64, 574 gpu::gles2::MemoryTracker::kUnmanaged); 575 Manage(); 576 EXPECT_EQ(stub1.BytesWhenVisible(), 8u); 577 578 // Far-oversubscribe the entire FB, and make sure we stay at 579 // the minimum allocation, and don't blow up. 580 memmgr_.TrackMemoryAllocatedChange( 581 stub1.tracking_group_.get(), 582 64, 583 999, 584 gpu::gles2::MemoryTracker::kUnmanaged); 585 Manage(); 586 EXPECT_EQ(stub1.BytesWhenVisible(), 8u); 587 588 // Delete all tracked memory so we don't hit leak checks. 589 memmgr_.TrackMemoryAllocatedChange( 590 stub1.tracking_group_.get(), 591 999, 592 0, 593 gpu::gles2::MemoryTracker::kUnmanaged); 594} 595 596// Test the default allocation levels are used. 597TEST_F(GpuMemoryManagerTest, DefaultAllocation) { 598 // Set memory manager constants for this test 599 memmgr_.TestingSetAvailableGpuMemory(64); 600 memmgr_.TestingSetMinimumClientAllocation(8); 601 memmgr_.TestingSetDefaultClientAllocation(16); 602 603 FakeClient stub1(&memmgr_, GenerateUniqueSurfaceId(), true); 604 605 // Expect that a client which has not sent stats receive at 606 // least the default allocation. 607 Manage(); 608 EXPECT_GE(stub1.BytesWhenVisible(), 609 memmgr_.GetDefaultClientAllocation()); 610} 611 612} // namespace content 613