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
{
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
24 class FakeMemoryTracker
: public gpu::gles2::MemoryTracker
{
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
{
35 virtual ~FakeMemoryTracker() {
41 // This class is used to collect all stub assignments during a
43 class ClientAssignmentCollector
{
45 struct ClientMemoryStat
{
46 GpuMemoryAllocation allocation
;
48 typedef base::hash_map
<GpuMemoryManagerClient
*, ClientMemoryStat
>
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
;
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
{
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
)
85 share_group_(share_group
),
86 memory_tracker_(NULL
) {
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
)
100 memory_tracker_(NULL
) {
101 memory_tracker_
= new FakeMemoryTracker();
102 tracking_group_
.reset(
103 memmgr_
->CreateTrackingGroup(0, memory_tracker_
.get()));
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
{
116 ClientAssignmentCollector::AddClientStat(this, alloc
);
119 virtual bool GetTotalGpuMemory(uint64
* bytes
) OVERRIDE
{
120 if (total_gpu_memory_
) {
121 *bytes
= total_gpu_memory_
;
126 void SetTotalGpuMemory(uint64 bytes
) { total_gpu_memory_
= bytes
; }
128 virtual gpu::gles2::MemoryTracker
* GetMemoryTracker() const OVERRIDE
{
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
{
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;
211 ClientAssignmentCollector::ClearAllStats();
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());
225 uint64
GetAvailableGpuMemory() {
226 return memmgr_
.GetAvailableGpuMemory();
229 uint64
GetMaximumClientAllocation() {
230 return memmgr_
.GetMaximumClientAllocation();
233 uint64
GetMinimumClientAllocation() {
234 return memmgr_
.GetMinimumClientAllocation();
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);
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
);
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
);
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
);
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);
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
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
);
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
);
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);
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);
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);
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);
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);
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
440 stub_ignore_b
.SetVisible(true);
441 stub_ignore_b
.SetVisible(false);
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);
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.
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
;
529 stats
= ClientAssignmentCollector::GetClientStatsForLastManage();
530 EXPECT_EQ(stats
.size(), 0ul);
532 FakeClient
stub1(&memmgr_
, GenerateUniqueSurfaceId(), true);
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
);
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);
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);
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);
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);
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);
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);
736 EXPECT_GT(stub1
.BytesWhenNotVisible(), 0u);
737 EXPECT_GT(stub2
.BytesWhenNotVisible(), 0u);
738 EXPECT_GT(stub3
.BytesWhenNotVisible(), 0u);
740 memmgr_
.allow_nonvisible_memory_
= false;
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);
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);
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);
782 EXPECT_GE(stub2
.BytesWhenNotVisible(), bytes_when_not_visible_expected
);
783 stub2
.SetVisible(false);
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);
800 EXPECT_GE(stub1
.BytesWhenVisible(), 32u);
802 // Now allocate some unmanaged memory and make sure the amount
804 memmgr_
.TrackMemoryAllocatedChange(
805 stub1
.tracking_group_
.get(),
808 gpu::gles2::MemoryTracker::kUnmanaged
);
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
);
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(),
828 gpu::gles2::MemoryTracker::kUnmanaged
);
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(),
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.
852 EXPECT_GE(stub1
.BytesWhenVisible(),
853 memmgr_
.GetDefaultClientAllocation());
854 EXPECT_EQ(stub1
.BytesWhenNotVisible(), 0u);
857 } // namespace content