- add sources.
[platform/framework/web/crosswalk.git] / src / content / common / gpu / gpu_memory_manager_unittest.cc
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
13 using gpu::MemoryAllocation;
14 using gpu::ManagedMemoryStats;
15
16 #if defined(COMPILER_GCC)
17 namespace BASE_HASH_NAMESPACE {
18 template<>
19 struct 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
27 class 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
42 namespace content {
43
44 // This class is used to collect all stub assignments during a
45 // Manage() call.
46 class 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
70 ClientAssignmentCollector::ClientMemoryStatMap
71     ClientAssignmentCollector::client_memory_stats_for_last_manage_;
72
73 class 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
162 class 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.
249 TEST_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.
279 TEST_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.
307 TEST_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.
329 TEST_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.
355 TEST_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.
399 TEST_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
457 TEST_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.
476 TEST_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.
545 TEST_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.
597 TEST_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