Respond with QuotaExceededError when IndexedDB has no disk space on open.
[chromium-blink-merge.git] / content / common / gpu / gpu_memory_manager_unittest.cc
blobe008a47777221a3caab61170f31153225cc2699f
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 "content/common/gpu/gpu_memory_allocation.h"
6 #include "content/common/gpu/gpu_memory_manager.h"
7 #include "content/common/gpu/gpu_memory_manager_client.h"
8 #include "content/common/gpu/gpu_memory_tracking.h"
9 #include "ui/gfx/size_conversions.h"
11 #include "testing/gtest/include/gtest/gtest.h"
13 #if defined(COMPILER_GCC)
14 namespace BASE_HASH_NAMESPACE {
15 template<>
16 struct hash<content::GpuMemoryManagerClient*> {
17 uint64 operator()(content::GpuMemoryManagerClient* ptr) const {
18 return hash<uint64>()(reinterpret_cast<uint64>(ptr));
21 } // namespace BASE_HASH_NAMESPACE
22 #endif // COMPILER
24 class FakeMemoryTracker : public gpu::gles2::MemoryTracker {
25 public:
26 virtual void TrackMemoryAllocatedChange(
27 size_t /* old_size */,
28 size_t /* new_size */,
29 gpu::gles2::MemoryTracker::Pool /* pool */) OVERRIDE {
31 virtual bool EnsureGPUMemoryAvailable(size_t /* size_needed */) OVERRIDE {
32 return true;
34 private:
35 virtual ~FakeMemoryTracker() {
39 namespace content {
41 // This class is used to collect all stub assignments during a
42 // Manage() call.
43 class ClientAssignmentCollector {
44 public:
45 struct ClientMemoryStat {
46 GpuMemoryAllocation allocation;
48 typedef base::hash_map<GpuMemoryManagerClient*, ClientMemoryStat>
49 ClientMemoryStatMap;
51 static const ClientMemoryStatMap& GetClientStatsForLastManage() {
52 return client_memory_stats_for_last_manage_;
54 static void ClearAllStats() {
55 client_memory_stats_for_last_manage_.clear();
57 static void AddClientStat(GpuMemoryManagerClient* client,
58 const GpuMemoryAllocation& allocation) {
59 DCHECK(!client_memory_stats_for_last_manage_.count(client));
60 client_memory_stats_for_last_manage_[client].allocation = allocation;
63 private:
64 static ClientMemoryStatMap client_memory_stats_for_last_manage_;
67 ClientAssignmentCollector::ClientMemoryStatMap
68 ClientAssignmentCollector::client_memory_stats_for_last_manage_;
70 class FakeClient : public GpuMemoryManagerClient {
71 public:
72 GpuMemoryManager* memmgr_;
73 GpuMemoryAllocation allocation_;
74 uint64 total_gpu_memory_;
75 gfx::Size surface_size_;
76 GpuMemoryManagerClient* share_group_;
77 scoped_refptr<gpu::gles2::MemoryTracker> memory_tracker_;
78 scoped_ptr<GpuMemoryTrackingGroup> tracking_group_;
79 scoped_ptr<GpuMemoryManagerClientState> client_state_;
81 // This will create a client with no surface
82 FakeClient(GpuMemoryManager* memmgr, GpuMemoryManagerClient* share_group)
83 : memmgr_(memmgr),
84 total_gpu_memory_(0),
85 share_group_(share_group),
86 memory_tracker_(NULL) {
87 if (!share_group_) {
88 memory_tracker_ = new FakeMemoryTracker();
89 tracking_group_.reset(
90 memmgr_->CreateTrackingGroup(0, memory_tracker_.get()));
92 client_state_.reset(memmgr_->CreateClientState(this, false, true));
95 // This will create a client with a surface
96 FakeClient(GpuMemoryManager* memmgr, int32 surface_id, bool visible)
97 : memmgr_(memmgr),
98 total_gpu_memory_(0),
99 share_group_(NULL),
100 memory_tracker_(NULL) {
101 memory_tracker_ = new FakeMemoryTracker();
102 tracking_group_.reset(
103 memmgr_->CreateTrackingGroup(0, memory_tracker_.get()));
104 client_state_.reset(
105 memmgr_->CreateClientState(this, surface_id != 0, visible));
108 virtual ~FakeClient() {
109 client_state_.reset();
110 tracking_group_.reset();
111 memory_tracker_ = NULL;
114 virtual void SetMemoryAllocation(const GpuMemoryAllocation& alloc) OVERRIDE {
115 allocation_ = alloc;
116 ClientAssignmentCollector::AddClientStat(this, alloc);
119 virtual bool GetTotalGpuMemory(uint64* bytes) OVERRIDE {
120 if (total_gpu_memory_) {
121 *bytes = total_gpu_memory_;
122 return true;
124 return false;
126 void SetTotalGpuMemory(uint64 bytes) { total_gpu_memory_ = bytes; }
128 virtual gpu::gles2::MemoryTracker* GetMemoryTracker() const OVERRIDE {
129 if (share_group_)
130 return share_group_->GetMemoryTracker();
131 return memory_tracker_.get();
134 virtual gfx::Size GetSurfaceSize() const OVERRIDE {
135 return surface_size_;
137 void SetSurfaceSize(gfx::Size size) { surface_size_ = size; }
139 void SetVisible(bool visible) {
140 client_state_->SetVisible(visible);
143 void SetManagedMemoryStats(const GpuManagedMemoryStats& stats) {
144 client_state_->SetManagedMemoryStats(stats);
147 uint64 BytesWhenVisible() const {
148 return allocation_.renderer_allocation.bytes_limit_when_visible;
151 uint64 BytesWhenNotVisible() const {
152 return allocation_.renderer_allocation.bytes_limit_when_not_visible;
156 class GpuMemoryManagerTest : public testing::Test {
157 protected:
158 static const uint64 kFrontbufferLimitForTest = 3;
160 GpuMemoryManagerTest()
161 : memmgr_(0, kFrontbufferLimitForTest) {
162 memmgr_.TestingDisableScheduleManage();
163 memmgr_.allow_nonvisible_memory_ = true;
166 virtual void SetUp() {
169 static int32 GenerateUniqueSurfaceId() {
170 static int32 surface_id_ = 1;
171 return surface_id_++;
174 bool IsAllocationForegroundForSurfaceYes(
175 const GpuMemoryAllocation& alloc) {
176 return alloc.browser_allocation.suggest_have_frontbuffer &&
177 !alloc.renderer_allocation.have_backbuffer_when_not_visible;
179 bool IsAllocationBackgroundForSurfaceYes(
180 const GpuMemoryAllocation& alloc) {
181 return alloc.browser_allocation.suggest_have_frontbuffer &&
182 !alloc.renderer_allocation.have_backbuffer_when_not_visible;
184 bool IsAllocationHibernatedForSurfaceYes(
185 const GpuMemoryAllocation& alloc) {
186 return !alloc.browser_allocation.suggest_have_frontbuffer &&
187 !alloc.renderer_allocation.have_backbuffer_when_not_visible;
189 bool IsAllocationForegroundForSurfaceNo(
190 const GpuMemoryAllocation& alloc) {
191 return !alloc.browser_allocation.suggest_have_frontbuffer &&
192 !alloc.renderer_allocation.have_backbuffer_when_not_visible &&
193 alloc.renderer_allocation.bytes_limit_when_visible ==
194 GetMinimumClientAllocation();
196 bool IsAllocationBackgroundForSurfaceNo(
197 const GpuMemoryAllocation& alloc) {
198 return !alloc.browser_allocation.suggest_have_frontbuffer &&
199 !alloc.renderer_allocation.have_backbuffer_when_not_visible &&
200 alloc.renderer_allocation.bytes_limit_when_visible ==
201 GetMinimumClientAllocation();
203 bool IsAllocationHibernatedForSurfaceNo(
204 const GpuMemoryAllocation& alloc) {
205 return !alloc.browser_allocation.suggest_have_frontbuffer &&
206 !alloc.renderer_allocation.have_backbuffer_when_not_visible &&
207 alloc.renderer_allocation.bytes_limit_when_visible == 0;
210 void Manage() {
211 ClientAssignmentCollector::ClearAllStats();
212 memmgr_.Manage();
215 uint64 CalcAvailableFromGpuTotal(uint64 bytes) {
216 return GpuMemoryManager::CalcAvailableFromGpuTotal(bytes);
219 uint64 CalcAvailableClamped(uint64 bytes) {
220 bytes = std::max(bytes, memmgr_.GetDefaultAvailableGpuMemory());
221 bytes = std::min(bytes, memmgr_.GetMaximumTotalGpuMemory());
222 return bytes;
225 uint64 GetAvailableGpuMemory() {
226 return memmgr_.GetAvailableGpuMemory();
229 uint64 GetMaximumClientAllocation() {
230 return memmgr_.GetMaximumClientAllocation();
233 uint64 GetMinimumClientAllocation() {
234 return memmgr_.GetMinimumClientAllocation();
237 void SetClientStats(
238 FakeClient* client,
239 uint64 required,
240 uint64 nicetohave) {
241 client->SetManagedMemoryStats(
242 GpuManagedMemoryStats(required, nicetohave, 0, false));
245 GpuMemoryManager memmgr_;
248 // Test GpuMemoryManager::Manage basic functionality.
249 // Expect memory allocation to set suggest_have_frontbuffer/backbuffer
250 // according to visibility and last used time for stubs with surface.
251 // Expect memory allocation to be shared according to share groups for stubs
252 // without a surface.
253 TEST_F(GpuMemoryManagerTest, TestManageBasicFunctionality) {
254 // Test stubs with surface.
255 FakeClient stub1(&memmgr_, GenerateUniqueSurfaceId(), true),
256 stub2(&memmgr_, GenerateUniqueSurfaceId(), false);
258 Manage();
259 EXPECT_TRUE(IsAllocationForegroundForSurfaceYes(stub1.allocation_));
260 EXPECT_TRUE(IsAllocationBackgroundForSurfaceYes(stub2.allocation_));
262 // Test stubs without surface, with share group of 1 stub.
263 FakeClient stub3(&memmgr_, &stub1), stub4(&memmgr_, &stub2);
265 Manage();
266 EXPECT_TRUE(IsAllocationForegroundForSurfaceYes(stub1.allocation_));
267 EXPECT_TRUE(IsAllocationBackgroundForSurfaceYes(stub2.allocation_));
268 EXPECT_TRUE(IsAllocationForegroundForSurfaceNo(stub3.allocation_));
269 EXPECT_TRUE(IsAllocationBackgroundForSurfaceNo(stub4.allocation_));
271 // Test stub without surface, with share group of multiple stubs.
272 FakeClient stub5(&memmgr_ , &stub2);
274 Manage();
275 EXPECT_TRUE(IsAllocationForegroundForSurfaceNo(stub4.allocation_));
278 // Test GpuMemoryManager::Manage functionality: changing visibility.
279 // Expect memory allocation to set suggest_have_frontbuffer/backbuffer
280 // according to visibility and last used time for stubs with surface.
281 // Expect memory allocation to be shared according to share groups for stubs
282 // without a surface.
283 TEST_F(GpuMemoryManagerTest, TestManageChangingVisibility) {
284 FakeClient stub1(&memmgr_, GenerateUniqueSurfaceId(), true),
285 stub2(&memmgr_, GenerateUniqueSurfaceId(), false);
287 FakeClient stub3(&memmgr_, &stub1), stub4(&memmgr_, &stub2);
288 FakeClient stub5(&memmgr_ , &stub2);
290 Manage();
291 EXPECT_TRUE(IsAllocationForegroundForSurfaceYes(stub1.allocation_));
292 EXPECT_TRUE(IsAllocationBackgroundForSurfaceYes(stub2.allocation_));
293 EXPECT_TRUE(IsAllocationForegroundForSurfaceNo(stub3.allocation_));
294 EXPECT_TRUE(IsAllocationBackgroundForSurfaceNo(stub4.allocation_));
295 EXPECT_TRUE(IsAllocationForegroundForSurfaceNo(stub5.allocation_));
297 stub1.SetVisible(false);
298 stub2.SetVisible(true);
300 Manage();
301 EXPECT_TRUE(IsAllocationBackgroundForSurfaceYes(stub1.allocation_));
302 EXPECT_TRUE(IsAllocationForegroundForSurfaceYes(stub2.allocation_));
303 EXPECT_TRUE(IsAllocationBackgroundForSurfaceNo(stub3.allocation_));
304 EXPECT_TRUE(IsAllocationForegroundForSurfaceNo(stub4.allocation_));
305 EXPECT_TRUE(IsAllocationForegroundForSurfaceNo(stub5.allocation_));
308 // Test GpuMemoryManager::Manage functionality: Test more than threshold number
309 // of visible stubs.
310 // Expect all allocations to continue to have frontbuffer.
311 TEST_F(GpuMemoryManagerTest, TestManageManyVisibleStubs) {
312 FakeClient stub1(&memmgr_, GenerateUniqueSurfaceId(), true),
313 stub2(&memmgr_, GenerateUniqueSurfaceId(), true),
314 stub3(&memmgr_, GenerateUniqueSurfaceId(), true),
315 stub4(&memmgr_, GenerateUniqueSurfaceId(), true);
317 FakeClient stub5(&memmgr_ , &stub1), stub6(&memmgr_ , &stub2);
318 FakeClient stub7(&memmgr_ , &stub2);
320 Manage();
321 EXPECT_TRUE(IsAllocationForegroundForSurfaceYes(stub1.allocation_));
322 EXPECT_TRUE(IsAllocationForegroundForSurfaceYes(stub2.allocation_));
323 EXPECT_TRUE(IsAllocationForegroundForSurfaceYes(stub3.allocation_));
324 EXPECT_TRUE(IsAllocationForegroundForSurfaceYes(stub4.allocation_));
325 EXPECT_TRUE(IsAllocationForegroundForSurfaceNo(stub5.allocation_));
326 EXPECT_TRUE(IsAllocationForegroundForSurfaceNo(stub6.allocation_));
327 EXPECT_TRUE(IsAllocationForegroundForSurfaceNo(stub7.allocation_));
330 // Test GpuMemoryManager::Manage functionality: Test more than threshold number
331 // of not visible stubs.
332 // Expect the stubs surpassing the threshold to not have a backbuffer.
333 TEST_F(GpuMemoryManagerTest, TestManageManyNotVisibleStubs) {
334 FakeClient stub1(&memmgr_, GenerateUniqueSurfaceId(), true),
335 stub2(&memmgr_, GenerateUniqueSurfaceId(), true),
336 stub3(&memmgr_, GenerateUniqueSurfaceId(), true),
337 stub4(&memmgr_, GenerateUniqueSurfaceId(), true);
338 stub4.SetVisible(false);
339 stub3.SetVisible(false);
340 stub2.SetVisible(false);
341 stub1.SetVisible(false);
343 FakeClient stub5(&memmgr_ , &stub1), stub6(&memmgr_ , &stub4);
344 FakeClient stub7(&memmgr_ , &stub1);
346 Manage();
347 EXPECT_TRUE(IsAllocationBackgroundForSurfaceYes(stub1.allocation_));
348 EXPECT_TRUE(IsAllocationBackgroundForSurfaceYes(stub2.allocation_));
349 EXPECT_TRUE(IsAllocationBackgroundForSurfaceYes(stub3.allocation_));
350 EXPECT_TRUE(IsAllocationHibernatedForSurfaceYes(stub4.allocation_));
351 EXPECT_TRUE(IsAllocationBackgroundForSurfaceNo(stub5.allocation_));
352 EXPECT_TRUE(IsAllocationHibernatedForSurfaceNo(stub6.allocation_));
353 EXPECT_TRUE(IsAllocationBackgroundForSurfaceNo(stub7.allocation_));
356 // Test GpuMemoryManager::Manage functionality: Test changing the last used
357 // time of stubs when doing so causes change in which stubs surpass threshold.
358 // Expect frontbuffer to be dropped for the older stub.
359 TEST_F(GpuMemoryManagerTest, TestManageChangingLastUsedTime) {
360 FakeClient stub1(&memmgr_, GenerateUniqueSurfaceId(), true),
361 stub2(&memmgr_, GenerateUniqueSurfaceId(), true),
362 stub3(&memmgr_, GenerateUniqueSurfaceId(), true),
363 stub4(&memmgr_, GenerateUniqueSurfaceId(), true);
365 FakeClient stub5(&memmgr_ , &stub3), stub6(&memmgr_ , &stub4);
366 FakeClient stub7(&memmgr_ , &stub3);
368 // Make stub4 be the least-recently-used client
369 stub4.SetVisible(false);
370 stub3.SetVisible(false);
371 stub2.SetVisible(false);
372 stub1.SetVisible(false);
374 Manage();
375 EXPECT_TRUE(IsAllocationBackgroundForSurfaceYes(stub1.allocation_));
376 EXPECT_TRUE(IsAllocationBackgroundForSurfaceYes(stub2.allocation_));
377 EXPECT_TRUE(IsAllocationBackgroundForSurfaceYes(stub3.allocation_));
378 EXPECT_TRUE(IsAllocationHibernatedForSurfaceYes(stub4.allocation_));
379 EXPECT_TRUE(IsAllocationBackgroundForSurfaceNo(stub5.allocation_));
380 EXPECT_TRUE(IsAllocationHibernatedForSurfaceNo(stub6.allocation_));
381 EXPECT_TRUE(IsAllocationBackgroundForSurfaceNo(stub7.allocation_));
383 // Make stub3 become the least-recently-used client.
384 stub2.SetVisible(true);
385 stub2.SetVisible(false);
386 stub4.SetVisible(true);
387 stub4.SetVisible(false);
389 Manage();
390 EXPECT_TRUE(IsAllocationBackgroundForSurfaceYes(stub1.allocation_));
391 EXPECT_TRUE(IsAllocationBackgroundForSurfaceYes(stub2.allocation_));
392 EXPECT_TRUE(IsAllocationHibernatedForSurfaceYes(stub3.allocation_));
393 EXPECT_TRUE(IsAllocationBackgroundForSurfaceYes(stub4.allocation_));
394 EXPECT_TRUE(IsAllocationHibernatedForSurfaceNo(stub5.allocation_));
395 EXPECT_TRUE(IsAllocationBackgroundForSurfaceNo(stub6.allocation_));
396 EXPECT_TRUE(IsAllocationHibernatedForSurfaceNo(stub7.allocation_));
399 // Test GpuMemoryManager::Manage functionality: Test changing importance of
400 // enough stubs so that every stub in share group crosses threshold.
401 // Expect memory allocation of the stubs without surface to share memory
402 // allocation with the most visible stub in share group.
403 TEST_F(GpuMemoryManagerTest, TestManageChangingImportanceShareGroup) {
404 FakeClient stub_ignore_a(&memmgr_, GenerateUniqueSurfaceId(), true),
405 stub_ignore_b(&memmgr_, GenerateUniqueSurfaceId(), false),
406 stub_ignore_c(&memmgr_, GenerateUniqueSurfaceId(), false);
407 FakeClient stub1(&memmgr_, GenerateUniqueSurfaceId(), false),
408 stub2(&memmgr_, GenerateUniqueSurfaceId(), false);
410 FakeClient stub3(&memmgr_, &stub2), stub4(&memmgr_, &stub2);
412 // stub1 and stub2 keep their non-hibernated state because they're
413 // either visible or the 2 most recently used clients (through the
414 // first three checks).
415 stub1.SetVisible(true);
416 stub2.SetVisible(true);
417 Manage();
418 EXPECT_TRUE(IsAllocationForegroundForSurfaceYes(stub1.allocation_));
419 EXPECT_TRUE(IsAllocationForegroundForSurfaceYes(stub2.allocation_));
420 EXPECT_TRUE(IsAllocationForegroundForSurfaceNo(stub3.allocation_));
421 EXPECT_TRUE(IsAllocationForegroundForSurfaceNo(stub4.allocation_));
423 stub1.SetVisible(false);
424 Manage();
425 EXPECT_TRUE(IsAllocationBackgroundForSurfaceYes(stub1.allocation_));
426 EXPECT_TRUE(IsAllocationForegroundForSurfaceYes(stub2.allocation_));
427 EXPECT_TRUE(IsAllocationBackgroundForSurfaceNo(stub3.allocation_));
428 EXPECT_TRUE(IsAllocationForegroundForSurfaceNo(stub4.allocation_));
430 stub2.SetVisible(false);
431 Manage();
432 EXPECT_TRUE(IsAllocationBackgroundForSurfaceYes(stub1.allocation_));
433 EXPECT_TRUE(IsAllocationBackgroundForSurfaceYes(stub2.allocation_));
434 EXPECT_TRUE(IsAllocationBackgroundForSurfaceNo(stub3.allocation_));
435 EXPECT_TRUE(IsAllocationBackgroundForSurfaceNo(stub4.allocation_));
437 // stub_ignore_b will cause stub1 to become hibernated (because
438 // stub_ignore_a, stub_ignore_b, and stub2 are all non-hibernated and more
439 // important).
440 stub_ignore_b.SetVisible(true);
441 stub_ignore_b.SetVisible(false);
442 Manage();
443 EXPECT_TRUE(IsAllocationHibernatedForSurfaceYes(stub1.allocation_));
444 EXPECT_TRUE(IsAllocationBackgroundForSurfaceYes(stub2.allocation_));
445 EXPECT_TRUE(IsAllocationBackgroundForSurfaceNo(stub3.allocation_));
446 EXPECT_TRUE(IsAllocationBackgroundForSurfaceNo(stub4.allocation_));
448 // stub_ignore_c will cause stub2 to become hibernated (because
449 // stub_ignore_a, stub_ignore_b, and stub_ignore_c are all non-hibernated
450 // and more important).
451 stub_ignore_c.SetVisible(true);
452 stub_ignore_c.SetVisible(false);
453 Manage();
454 EXPECT_TRUE(IsAllocationHibernatedForSurfaceYes(stub1.allocation_));
455 EXPECT_TRUE(IsAllocationHibernatedForSurfaceYes(stub2.allocation_));
456 EXPECT_TRUE(IsAllocationHibernatedForSurfaceNo(stub3.allocation_));
457 EXPECT_TRUE(IsAllocationHibernatedForSurfaceNo(stub4.allocation_));
460 // Test GpuMemoryManager::UpdateAvailableGpuMemory functionality
461 TEST_F(GpuMemoryManagerTest, TestUpdateAvailableGpuMemory) {
462 FakeClient stub1(&memmgr_, GenerateUniqueSurfaceId(), true),
463 stub2(&memmgr_, GenerateUniqueSurfaceId(), false),
464 stub3(&memmgr_, GenerateUniqueSurfaceId(), true),
465 stub4(&memmgr_, GenerateUniqueSurfaceId(), false);
466 // We take the lowest GPU's total memory as the limit
467 uint64 expected = 400 * 1024 * 1024;
468 stub1.SetTotalGpuMemory(expected); // GPU Memory
469 stub2.SetTotalGpuMemory(expected - 1024 * 1024); // Smaller but not visible.
470 stub3.SetTotalGpuMemory(expected + 1024 * 1024); // Visible but larger.
471 stub4.SetTotalGpuMemory(expected + 1024 * 1024); // Not visible and larger.
472 Manage();
473 uint64 bytes_expected = CalcAvailableFromGpuTotal(expected);
474 EXPECT_EQ(GetAvailableGpuMemory(), CalcAvailableClamped(bytes_expected));
478 // Test GpuMemoryAllocation comparison operators: Iterate over all possible
479 // combinations of gpu_resource_size_in_bytes, suggest_have_backbuffer, and
480 // suggest_have_frontbuffer, and make sure allocations with equal values test
481 // equal and non equal values test not equal.
482 TEST_F(GpuMemoryManagerTest, GpuMemoryAllocationCompareTests) {
483 std::vector<int> gpu_resource_size_in_bytes_values;
484 gpu_resource_size_in_bytes_values.push_back(0);
485 gpu_resource_size_in_bytes_values.push_back(1);
486 gpu_resource_size_in_bytes_values.push_back(12345678);
488 std::vector<GpuMemoryAllocation::BufferAllocation>
489 suggested_buffer_allocation_values;
490 suggested_buffer_allocation_values.push_back(
491 GpuMemoryAllocation::kHasFrontbuffer);
492 suggested_buffer_allocation_values.push_back(
493 GpuMemoryAllocation::kHasFrontbuffer);
494 suggested_buffer_allocation_values.push_back(
495 GpuMemoryAllocation::kHasNoFrontbuffer);
496 suggested_buffer_allocation_values.push_back(
497 GpuMemoryAllocation::kHasNoFrontbuffer);
499 for (size_t i = 0; i != gpu_resource_size_in_bytes_values.size(); ++i) {
500 for (size_t j = 0; j != suggested_buffer_allocation_values.size(); ++j) {
501 uint64 sz = gpu_resource_size_in_bytes_values[i];
502 GpuMemoryAllocation::BufferAllocation buffer_allocation =
503 suggested_buffer_allocation_values[j];
504 GpuMemoryAllocation allocation(sz, buffer_allocation);
506 EXPECT_TRUE(allocation.Equals(
507 GpuMemoryAllocation(sz, buffer_allocation)));
508 EXPECT_FALSE(allocation.Equals(
509 GpuMemoryAllocation(sz+1, buffer_allocation)));
511 for (size_t k = 0; k != suggested_buffer_allocation_values.size(); ++k) {
512 GpuMemoryAllocation::BufferAllocation buffer_allocation_other =
513 suggested_buffer_allocation_values[k];
514 if (buffer_allocation == buffer_allocation_other) continue;
515 EXPECT_FALSE(allocation.Equals(
516 GpuMemoryAllocation(sz, buffer_allocation_other)));
522 // Test GpuMemoryManager Stub Memory Stats functionality:
523 // Creates various surface/non-surface stubs and switches stub visibility and
524 // tests to see that stats data structure values are correct.
525 TEST_F(GpuMemoryManagerTest, StubMemoryStatsForLastManageTests) {
526 ClientAssignmentCollector::ClientMemoryStatMap stats;
528 Manage();
529 stats = ClientAssignmentCollector::GetClientStatsForLastManage();
530 EXPECT_EQ(stats.size(), 0ul);
532 FakeClient stub1(&memmgr_, GenerateUniqueSurfaceId(), true);
533 Manage();
534 stats = ClientAssignmentCollector::GetClientStatsForLastManage();
535 uint64 stub1allocation1 =
536 stats[&stub1].allocation.renderer_allocation.bytes_limit_when_visible;
538 EXPECT_EQ(stats.size(), 1ul);
539 EXPECT_GT(stub1allocation1, 0ul);
541 FakeClient stub2(&memmgr_, &stub1);
542 Manage();
543 stats = ClientAssignmentCollector::GetClientStatsForLastManage();
544 EXPECT_EQ(stats.count(&stub1), 1ul);
545 uint64 stub1allocation2 =
546 stats[&stub1].allocation.renderer_allocation.bytes_limit_when_visible;
547 EXPECT_EQ(stats.count(&stub2), 1ul);
548 uint64 stub2allocation2 =
549 stats[&stub2].allocation.renderer_allocation.bytes_limit_when_visible;
551 EXPECT_EQ(stats.size(), 2ul);
552 EXPECT_GT(stub1allocation2, 0ul);
553 EXPECT_GT(stub2allocation2, 0ul);
554 if (stub1allocation2 != GetMaximumClientAllocation())
555 EXPECT_LT(stub1allocation2, stub1allocation1);
557 FakeClient stub3(&memmgr_, GenerateUniqueSurfaceId(), true);
558 Manage();
559 stats = ClientAssignmentCollector::GetClientStatsForLastManage();
560 uint64 stub1allocation3 =
561 stats[&stub1].allocation.renderer_allocation.bytes_limit_when_visible;
562 uint64 stub2allocation3 =
563 stats[&stub2].allocation.renderer_allocation.bytes_limit_when_visible;
564 uint64 stub3allocation3 =
565 stats[&stub3].allocation.renderer_allocation.bytes_limit_when_visible;
567 EXPECT_EQ(stats.size(), 3ul);
568 EXPECT_GT(stub1allocation3, 0ul);
569 EXPECT_GT(stub2allocation3, 0ul);
570 EXPECT_GT(stub3allocation3, 0ul);
571 if (stub1allocation3 != GetMaximumClientAllocation())
572 EXPECT_LT(stub1allocation3, stub1allocation2);
574 stub1.SetVisible(false);
576 Manage();
577 stats = ClientAssignmentCollector::GetClientStatsForLastManage();
578 uint64 stub1allocation4 =
579 stats[&stub1].allocation.renderer_allocation.bytes_limit_when_visible;
580 uint64 stub2allocation4 =
581 stats[&stub2].allocation.renderer_allocation.bytes_limit_when_visible;
582 uint64 stub3allocation4 =
583 stats[&stub3].allocation.renderer_allocation.bytes_limit_when_visible;
585 EXPECT_EQ(stats.size(), 3ul);
586 EXPECT_GT(stub1allocation4, 0ul);
587 EXPECT_GE(stub2allocation4, 0ul);
588 EXPECT_GT(stub3allocation4, 0ul);
589 if (stub3allocation3 != GetMaximumClientAllocation())
590 EXPECT_GT(stub3allocation4, stub3allocation3);
593 // Test GpuMemoryManager's managed memory tracking
594 TEST_F(GpuMemoryManagerTest, TestManagedUsageTracking) {
595 FakeClient stub1(&memmgr_, GenerateUniqueSurfaceId(), true),
596 stub2(&memmgr_, GenerateUniqueSurfaceId(), false);
597 EXPECT_EQ(0ul, memmgr_.bytes_allocated_managed_visible_);
598 EXPECT_EQ(0ul, memmgr_.bytes_allocated_managed_nonvisible_);
600 // Set memory allocations and verify the results are reflected.
601 stub1.SetManagedMemoryStats(GpuManagedMemoryStats(0, 0, 5, false));
602 stub2.SetManagedMemoryStats(GpuManagedMemoryStats(0, 0, 7, false));
603 EXPECT_EQ(5ul, memmgr_.bytes_allocated_managed_visible_);
604 EXPECT_EQ(7ul, memmgr_.bytes_allocated_managed_nonvisible_);
606 // Remove a visible client
607 stub1.client_state_.reset();
608 EXPECT_EQ(0ul, memmgr_.bytes_allocated_managed_visible_);
609 EXPECT_EQ(7ul, memmgr_.bytes_allocated_managed_nonvisible_);
610 EXPECT_EQ(0ul, memmgr_.bytes_allocated_managed_visible_);
611 EXPECT_EQ(7ul, memmgr_.bytes_allocated_managed_nonvisible_);
612 stub1.client_state_.reset(memmgr_.CreateClientState(&stub1, true, true));
613 EXPECT_EQ(0ul, memmgr_.bytes_allocated_managed_visible_);
614 EXPECT_EQ(7ul, memmgr_.bytes_allocated_managed_nonvisible_);
615 stub1.SetManagedMemoryStats(GpuManagedMemoryStats(0, 0, 5, false));
616 EXPECT_EQ(5ul, memmgr_.bytes_allocated_managed_visible_);
617 EXPECT_EQ(7ul, memmgr_.bytes_allocated_managed_nonvisible_);
619 // Remove a nonvisible client
620 stub2.client_state_.reset();
621 EXPECT_EQ(5ul, memmgr_.bytes_allocated_managed_visible_);
622 EXPECT_EQ(0ul, memmgr_.bytes_allocated_managed_nonvisible_);
623 EXPECT_EQ(5ul, memmgr_.bytes_allocated_managed_visible_);
624 EXPECT_EQ(0ul, memmgr_.bytes_allocated_managed_nonvisible_);
625 stub2.client_state_.reset(memmgr_.CreateClientState(&stub2, true, false));
626 EXPECT_EQ(5ul, memmgr_.bytes_allocated_managed_visible_);
627 EXPECT_EQ(0ul, memmgr_.bytes_allocated_managed_nonvisible_);
628 stub2.SetManagedMemoryStats(GpuManagedMemoryStats(0, 0, 7, false));
629 EXPECT_EQ(5ul, memmgr_.bytes_allocated_managed_visible_);
630 EXPECT_EQ(7ul, memmgr_.bytes_allocated_managed_nonvisible_);
632 // Create and then destroy some stubs, and verify their allocations go away.
634 FakeClient stub3(&memmgr_, GenerateUniqueSurfaceId(), true),
635 stub4(&memmgr_, GenerateUniqueSurfaceId(), false);
636 stub3.SetManagedMemoryStats(GpuManagedMemoryStats(0, 0, 1, false));
637 stub4.SetManagedMemoryStats(GpuManagedMemoryStats(0, 0, 2, false));
638 EXPECT_EQ(6ul, memmgr_.bytes_allocated_managed_visible_);
639 EXPECT_EQ(9ul, memmgr_.bytes_allocated_managed_nonvisible_);
641 EXPECT_EQ(5ul, memmgr_.bytes_allocated_managed_visible_);
642 EXPECT_EQ(7ul, memmgr_.bytes_allocated_managed_nonvisible_);
644 // Do no-op changes to stubs' visibility and make sure nothing chnages.
645 stub1.SetVisible(true);
646 stub2.SetVisible(false);
647 EXPECT_EQ(5ul, memmgr_.bytes_allocated_managed_visible_);
648 EXPECT_EQ(7ul, memmgr_.bytes_allocated_managed_nonvisible_);
650 // Change visbility state.
651 stub1.SetVisible(false);
652 stub2.SetVisible(true);
653 EXPECT_EQ(7ul, memmgr_.bytes_allocated_managed_visible_);
654 EXPECT_EQ(5ul, memmgr_.bytes_allocated_managed_nonvisible_);
656 // Increase allocation amounts.
657 stub1.SetManagedMemoryStats(GpuManagedMemoryStats(0, 0, 6, false));
658 stub2.SetManagedMemoryStats(GpuManagedMemoryStats(0, 0, 8, false));
659 EXPECT_EQ(8ul, memmgr_.bytes_allocated_managed_visible_);
660 EXPECT_EQ(6ul, memmgr_.bytes_allocated_managed_nonvisible_);
662 // Decrease allocation amounts.
663 stub1.SetManagedMemoryStats(GpuManagedMemoryStats(0, 0, 4, false));
664 stub2.SetManagedMemoryStats(GpuManagedMemoryStats(0, 0, 6, false));
665 EXPECT_EQ(6ul, memmgr_.bytes_allocated_managed_visible_);
666 EXPECT_EQ(4ul, memmgr_.bytes_allocated_managed_nonvisible_);
669 // Test nonvisible MRU behavior (the most recently used nonvisible clients
670 // keep their contents).
671 TEST_F(GpuMemoryManagerTest, BackgroundMru) {
672 // Set memory manager constants for this test. Note that the budget
673 // for backgrounded content will be 64/4 = 16.
674 memmgr_.TestingSetAvailableGpuMemory(64);
675 memmgr_.TestingSetMinimumClientAllocation(8);
677 uint64 bytes_when_not_visible_expected = 6u;
679 FakeClient stub1(&memmgr_, GenerateUniqueSurfaceId(), true);
680 FakeClient stub2(&memmgr_, GenerateUniqueSurfaceId(), true);
681 FakeClient stub3(&memmgr_, GenerateUniqueSurfaceId(), true);
683 // When all are visible, they should all be allowed to have memory
684 // should they become nonvisible.
685 SetClientStats(&stub1, 6, 23);
686 SetClientStats(&stub2, 6, 23);
687 SetClientStats(&stub3, 6, 23);
688 Manage();
689 EXPECT_GE(stub1.BytesWhenVisible(), 20u);
690 EXPECT_GE(stub2.BytesWhenVisible(), 20u);
691 EXPECT_GE(stub3.BytesWhenVisible(), 20u);
692 EXPECT_LT(stub1.BytesWhenVisible(), 22u);
693 EXPECT_LT(stub2.BytesWhenVisible(), 22u);
694 EXPECT_LT(stub3.BytesWhenVisible(), 22u);
695 EXPECT_GE(stub1.BytesWhenNotVisible(), bytes_when_not_visible_expected);
696 EXPECT_GE(stub2.BytesWhenNotVisible(), bytes_when_not_visible_expected);
697 EXPECT_GE(stub3.BytesWhenNotVisible(), bytes_when_not_visible_expected);
699 // Background stubs 1 and 2, and they should fit. All stubs should
700 // have their full nicetohave budget should they become visible.
701 stub2.SetVisible(false);
702 stub1.SetVisible(false);
703 Manage();
704 EXPECT_GE(stub1.BytesWhenVisible(), 23u);
705 EXPECT_GE(stub2.BytesWhenVisible(), 23u);
706 EXPECT_GE(stub3.BytesWhenVisible(), 23u);
707 EXPECT_LT(stub1.BytesWhenVisible(), 32u);
708 EXPECT_LT(stub2.BytesWhenVisible(), 32u);
709 EXPECT_GE(stub1.BytesWhenNotVisible(), bytes_when_not_visible_expected);
710 EXPECT_GE(stub2.BytesWhenNotVisible(), bytes_when_not_visible_expected);
711 EXPECT_GE(stub3.BytesWhenNotVisible(), bytes_when_not_visible_expected);
713 // Now background stub 3, and it should cause stub 2 to be
714 // evicted because it was set non-visible first
715 stub3.SetVisible(false);
716 Manage();
717 EXPECT_GE(stub1.BytesWhenNotVisible(), bytes_when_not_visible_expected);
718 EXPECT_EQ(stub2.BytesWhenNotVisible(), 0u);
719 EXPECT_GE(stub3.BytesWhenNotVisible(), bytes_when_not_visible_expected);
722 TEST_F(GpuMemoryManagerTest, AllowNonvisibleMemory) {
723 memmgr_.TestingSetAvailableGpuMemory(512);
724 memmgr_.TestingSetMinimumClientAllocation(16);
726 FakeClient stub1(&memmgr_, GenerateUniqueSurfaceId(), true);
727 FakeClient stub2(&memmgr_, GenerateUniqueSurfaceId(), true);
728 FakeClient stub3(&memmgr_, GenerateUniqueSurfaceId(), true);
730 memmgr_.allow_nonvisible_memory_ = true;
731 stub1.SetVisible(true);
732 SetClientStats(&stub1, 20, 80);
733 SetClientStats(&stub2, 20, 80);
734 SetClientStats(&stub3, 20, 80);
735 Manage();
736 EXPECT_GT(stub1.BytesWhenNotVisible(), 0u);
737 EXPECT_GT(stub2.BytesWhenNotVisible(), 0u);
738 EXPECT_GT(stub3.BytesWhenNotVisible(), 0u);
740 memmgr_.allow_nonvisible_memory_ = false;
741 Manage();
742 EXPECT_EQ(stub1.BytesWhenNotVisible(), 0u);
743 EXPECT_EQ(stub2.BytesWhenNotVisible(), 0u);
744 EXPECT_EQ(stub3.BytesWhenNotVisible(), 0u);
747 // Test that once a backgrounded client has dropped its resources, it
748 // doesn't get them back until it becomes visible again.
749 TEST_F(GpuMemoryManagerTest, BackgroundDiscardPersistent) {
750 // Set memory manager constants for this test. Note that the budget
751 // for backgrounded content will be 64/4 = 16.
752 memmgr_.TestingSetAvailableGpuMemory(64);
753 memmgr_.TestingSetMinimumClientAllocation(8);
755 uint64 bytes_when_not_visible_expected = 10ul;
756 if (!memmgr_.allow_nonvisible_memory_)
757 bytes_when_not_visible_expected = 0;
759 FakeClient stub1(&memmgr_, GenerateUniqueSurfaceId(), true);
760 FakeClient stub2(&memmgr_, GenerateUniqueSurfaceId(), true);
762 // Both clients should be able to keep their contents should one of
763 // them become nonvisible.
764 SetClientStats(&stub1, 10, 20);
765 SetClientStats(&stub2, 10, 20);
766 Manage();
767 EXPECT_GE(stub1.BytesWhenNotVisible(), bytes_when_not_visible_expected);
768 EXPECT_GE(stub2.BytesWhenNotVisible(), bytes_when_not_visible_expected);
770 // If they both go nonvisible, then only the most recently used client
771 // should keep its contents.
772 stub1.SetVisible(false);
773 stub2.SetVisible(false);
774 Manage();
775 EXPECT_EQ(stub1.BytesWhenNotVisible(), 0u);
776 EXPECT_GE(stub2.BytesWhenNotVisible(), bytes_when_not_visible_expected);
778 // When becoming visible, stub 2 should get its contents back, and
779 // retain them next time it is made nonvisible.
780 stub2.SetVisible(true);
781 Manage();
782 EXPECT_GE(stub2.BytesWhenNotVisible(), bytes_when_not_visible_expected);
783 stub2.SetVisible(false);
784 Manage();
785 EXPECT_GE(stub2.BytesWhenNotVisible(), bytes_when_not_visible_expected);
788 // Test tracking of unmanaged (e.g, WebGL) memory.
789 TEST_F(GpuMemoryManagerTest, UnmanagedTracking) {
790 // Set memory manager constants for this test
791 memmgr_.TestingSetAvailableGpuMemory(64);
792 memmgr_.TestingSetMinimumClientAllocation(8);
793 memmgr_.TestingSetUnmanagedLimitStep(16);
795 FakeClient stub1(&memmgr_, GenerateUniqueSurfaceId(), true);
797 // Expect that the one stub get its nicetohave level.
798 SetClientStats(&stub1, 16, 32);
799 Manage();
800 EXPECT_GE(stub1.BytesWhenVisible(), 32u);
802 // Now allocate some unmanaged memory and make sure the amount
803 // goes down.
804 memmgr_.TrackMemoryAllocatedChange(
805 stub1.tracking_group_.get(),
808 gpu::gles2::MemoryTracker::kUnmanaged);
809 Manage();
810 EXPECT_LT(stub1.BytesWhenVisible(), 24u);
812 // Now allocate the entire FB worth of unmanaged memory, and
813 // make sure that we stay stuck at the minimum tab allocation.
814 memmgr_.TrackMemoryAllocatedChange(
815 stub1.tracking_group_.get(),
818 gpu::gles2::MemoryTracker::kUnmanaged);
819 Manage();
820 EXPECT_EQ(stub1.BytesWhenVisible(), 8u);
822 // Far-oversubscribe the entire FB, and make sure we stay at
823 // the minimum allocation, and don't blow up.
824 memmgr_.TrackMemoryAllocatedChange(
825 stub1.tracking_group_.get(),
827 999,
828 gpu::gles2::MemoryTracker::kUnmanaged);
829 Manage();
830 EXPECT_EQ(stub1.BytesWhenVisible(), 8u);
832 // Delete all tracked memory so we don't hit leak checks.
833 memmgr_.TrackMemoryAllocatedChange(
834 stub1.tracking_group_.get(),
835 999,
837 gpu::gles2::MemoryTracker::kUnmanaged);
840 // Test the default allocation levels are used.
841 TEST_F(GpuMemoryManagerTest, DefaultAllocation) {
842 // Set memory manager constants for this test
843 memmgr_.TestingSetAvailableGpuMemory(64);
844 memmgr_.TestingSetMinimumClientAllocation(8);
845 memmgr_.TestingSetDefaultClientAllocation(16);
847 FakeClient stub1(&memmgr_, GenerateUniqueSurfaceId(), true);
849 // Expect that a client which has not sent stats receive at
850 // least the default allocation.
851 Manage();
852 EXPECT_GE(stub1.BytesWhenVisible(),
853 memmgr_.GetDefaultClientAllocation());
854 EXPECT_EQ(stub1.BytesWhenNotVisible(), 0u);
857 } // namespace content