Home | History | Annotate | Download | only in gpu
      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_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"
     10 
     11 #include "testing/gtest/include/gtest/gtest.h"
     12 
     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));
     19   }
     20 };
     21 }  // namespace BASE_HASH_NAMESPACE
     22 #endif  // COMPILER
     23 
     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 {
     30   }
     31   virtual bool EnsureGPUMemoryAvailable(size_t /* size_needed */) OVERRIDE {
     32     return true;
     33   }
     34  private:
     35   virtual ~FakeMemoryTracker() {
     36   }
     37 };
     38 
     39 namespace content {
     40 
     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;
     47   };
     48   typedef base::hash_map<GpuMemoryManagerClient*, ClientMemoryStat>
     49       ClientMemoryStatMap;
     50 
     51   static const ClientMemoryStatMap& GetClientStatsForLastManage() {
     52     return client_memory_stats_for_last_manage_;
     53   }
     54   static void ClearAllStats() {
     55     client_memory_stats_for_last_manage_.clear();
     56   }
     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;
     61   }
     62 
     63  private:
     64   static ClientMemoryStatMap client_memory_stats_for_last_manage_;
     65 };
     66 
     67 ClientAssignmentCollector::ClientMemoryStatMap
     68     ClientAssignmentCollector::client_memory_stats_for_last_manage_;
     69 
     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_;
     80 
     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()));
     91     }
     92     client_state_.reset(memmgr_->CreateClientState(this, false, true));
     93   }
     94 
     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));
    106   }
    107 
    108   virtual ~FakeClient() {
    109     client_state_.reset();
    110     tracking_group_.reset();
    111     memory_tracker_ = NULL;
    112   }
    113 
    114   virtual void SetMemoryAllocation(const GpuMemoryAllocation& alloc) OVERRIDE {
    115     allocation_ = alloc;
    116     ClientAssignmentCollector::AddClientStat(this, alloc);
    117   }
    118 
    119   virtual bool GetTotalGpuMemory(uint64* bytes) OVERRIDE {
    120     if (total_gpu_memory_) {
    121       *bytes = total_gpu_memory_;
    122       return true;
    123     }
    124     return false;
    125   }
    126   void SetTotalGpuMemory(uint64 bytes) { total_gpu_memory_ = bytes; }
    127 
    128   virtual gpu::gles2::MemoryTracker* GetMemoryTracker() const OVERRIDE {
    129     if (share_group_)
    130       return share_group_->GetMemoryTracker();
    131     return memory_tracker_.get();
    132   }
    133 
    134   virtual gfx::Size GetSurfaceSize() const OVERRIDE {
    135     return surface_size_;
    136   }
    137   void SetSurfaceSize(gfx::Size size) { surface_size_ = size; }
    138 
    139   void SetVisible(bool visible) {
    140     client_state_->SetVisible(visible);
    141   }
    142 
    143   void SetManagedMemoryStats(const GpuManagedMemoryStats& stats) {
    144     client_state_->SetManagedMemoryStats(stats);
    145   }
    146 
    147   uint64 BytesWhenVisible() const {
    148     return allocation_.renderer_allocation.bytes_limit_when_visible;
    149   }
    150 
    151   uint64 BytesWhenNotVisible() const {
    152     return allocation_.renderer_allocation.bytes_limit_when_not_visible;
    153   }
    154 };
    155 
    156 class GpuMemoryManagerTest : public testing::Test {
    157  protected:
    158   static const uint64 kFrontbufferLimitForTest = 3;
    159 
    160   GpuMemoryManagerTest()
    161       : memmgr_(0, kFrontbufferLimitForTest) {
    162     memmgr_.TestingDisableScheduleManage();
    163   }
    164 
    165   virtual void SetUp() {
    166   }
    167 
    168   static int32 GenerateUniqueSurfaceId() {
    169     static int32 surface_id_ = 1;
    170     return surface_id_++;
    171   }
    172 
    173   bool IsAllocationForegroundForSurfaceYes(
    174       const GpuMemoryAllocation& alloc) {
    175     return alloc.browser_allocation.suggest_have_frontbuffer &&
    176            !alloc.renderer_allocation.have_backbuffer_when_not_visible;
    177   }
    178   bool IsAllocationBackgroundForSurfaceYes(
    179       const GpuMemoryAllocation& alloc) {
    180     return alloc.browser_allocation.suggest_have_frontbuffer &&
    181            !alloc.renderer_allocation.have_backbuffer_when_not_visible;
    182   }
    183   bool IsAllocationHibernatedForSurfaceYes(
    184       const GpuMemoryAllocation& alloc) {
    185     return !alloc.browser_allocation.suggest_have_frontbuffer &&
    186            !alloc.renderer_allocation.have_backbuffer_when_not_visible;
    187   }
    188   bool IsAllocationForegroundForSurfaceNo(
    189       const GpuMemoryAllocation& alloc) {
    190     return !alloc.browser_allocation.suggest_have_frontbuffer &&
    191            !alloc.renderer_allocation.have_backbuffer_when_not_visible &&
    192            alloc.renderer_allocation.bytes_limit_when_visible ==
    193                GetMinimumClientAllocation();
    194   }
    195   bool IsAllocationBackgroundForSurfaceNo(
    196       const GpuMemoryAllocation& alloc) {
    197     return !alloc.browser_allocation.suggest_have_frontbuffer &&
    198            !alloc.renderer_allocation.have_backbuffer_when_not_visible &&
    199            alloc.renderer_allocation.bytes_limit_when_visible ==
    200                GetMinimumClientAllocation();
    201   }
    202   bool IsAllocationHibernatedForSurfaceNo(
    203       const GpuMemoryAllocation& alloc) {
    204     return !alloc.browser_allocation.suggest_have_frontbuffer &&
    205            !alloc.renderer_allocation.have_backbuffer_when_not_visible &&
    206            alloc.renderer_allocation.bytes_limit_when_visible == 0;
    207   }
    208 
    209   void Manage() {
    210     ClientAssignmentCollector::ClearAllStats();
    211     memmgr_.Manage();
    212   }
    213 
    214   uint64 CalcAvailableFromGpuTotal(uint64 bytes) {
    215     return GpuMemoryManager::CalcAvailableFromGpuTotal(bytes);
    216   }
    217 
    218   uint64 CalcAvailableClamped(uint64 bytes) {
    219     bytes = std::max(bytes, memmgr_.GetDefaultAvailableGpuMemory());
    220     bytes = std::min(bytes, memmgr_.GetMaximumTotalGpuMemory());
    221     return bytes;
    222   }
    223 
    224   uint64 GetAvailableGpuMemory() {
    225     return memmgr_.GetAvailableGpuMemory();
    226   }
    227 
    228   uint64 GetMaximumClientAllocation() {
    229     return memmgr_.GetMaximumClientAllocation();
    230   }
    231 
    232   uint64 GetMinimumClientAllocation() {
    233     return memmgr_.GetMinimumClientAllocation();
    234   }
    235 
    236   void SetClientStats(
    237       FakeClient* client,
    238       uint64 required,
    239       uint64 nicetohave) {
    240     client->SetManagedMemoryStats(
    241         GpuManagedMemoryStats(required, nicetohave, 0, false));
    242   }
    243 
    244   GpuMemoryManager memmgr_;
    245 };
    246 
    247 // Test GpuMemoryManager::Manage basic functionality.
    248 // Expect memory allocation to set suggest_have_frontbuffer/backbuffer
    249 // according to visibility and last used time for stubs with surface.
    250 // Expect memory allocation to be shared according to share groups for stubs
    251 // without a surface.
    252 TEST_F(GpuMemoryManagerTest, TestManageBasicFunctionality) {
    253   // Test stubs with surface.
    254   FakeClient stub1(&memmgr_, GenerateUniqueSurfaceId(), true),
    255              stub2(&memmgr_, GenerateUniqueSurfaceId(), false);
    256 
    257   Manage();
    258   EXPECT_TRUE(IsAllocationForegroundForSurfaceYes(stub1.allocation_));
    259   EXPECT_TRUE(IsAllocationBackgroundForSurfaceYes(stub2.allocation_));
    260 
    261   // Test stubs without surface, with share group of 1 stub.
    262   FakeClient stub3(&memmgr_, &stub1), stub4(&memmgr_, &stub2);
    263 
    264   Manage();
    265   EXPECT_TRUE(IsAllocationForegroundForSurfaceYes(stub1.allocation_));
    266   EXPECT_TRUE(IsAllocationBackgroundForSurfaceYes(stub2.allocation_));
    267   EXPECT_TRUE(IsAllocationForegroundForSurfaceNo(stub3.allocation_));
    268   EXPECT_TRUE(IsAllocationBackgroundForSurfaceNo(stub4.allocation_));
    269 
    270   // Test stub without surface, with share group of multiple stubs.
    271   FakeClient stub5(&memmgr_ , &stub2);
    272 
    273   Manage();
    274   EXPECT_TRUE(IsAllocationForegroundForSurfaceNo(stub4.allocation_));
    275 }
    276 
    277 // Test GpuMemoryManager::Manage functionality: changing visibility.
    278 // Expect memory allocation to set suggest_have_frontbuffer/backbuffer
    279 // according to visibility and last used time for stubs with surface.
    280 // Expect memory allocation to be shared according to share groups for stubs
    281 // without a surface.
    282 TEST_F(GpuMemoryManagerTest, TestManageChangingVisibility) {
    283   FakeClient stub1(&memmgr_, GenerateUniqueSurfaceId(), true),
    284              stub2(&memmgr_, GenerateUniqueSurfaceId(), false);
    285 
    286   FakeClient stub3(&memmgr_, &stub1), stub4(&memmgr_, &stub2);
    287   FakeClient stub5(&memmgr_ , &stub2);
    288 
    289   Manage();
    290   EXPECT_TRUE(IsAllocationForegroundForSurfaceYes(stub1.allocation_));
    291   EXPECT_TRUE(IsAllocationBackgroundForSurfaceYes(stub2.allocation_));
    292   EXPECT_TRUE(IsAllocationForegroundForSurfaceNo(stub3.allocation_));
    293   EXPECT_TRUE(IsAllocationBackgroundForSurfaceNo(stub4.allocation_));
    294   EXPECT_TRUE(IsAllocationForegroundForSurfaceNo(stub5.allocation_));
    295 
    296   stub1.SetVisible(false);
    297   stub2.SetVisible(true);
    298 
    299   Manage();
    300   EXPECT_TRUE(IsAllocationBackgroundForSurfaceYes(stub1.allocation_));
    301   EXPECT_TRUE(IsAllocationForegroundForSurfaceYes(stub2.allocation_));
    302   EXPECT_TRUE(IsAllocationBackgroundForSurfaceNo(stub3.allocation_));
    303   EXPECT_TRUE(IsAllocationForegroundForSurfaceNo(stub4.allocation_));
    304   EXPECT_TRUE(IsAllocationForegroundForSurfaceNo(stub5.allocation_));
    305 }
    306 
    307 // Test GpuMemoryManager::Manage functionality: Test more than threshold number
    308 // of visible stubs.
    309 // Expect all allocations to continue to have frontbuffer.
    310 TEST_F(GpuMemoryManagerTest, TestManageManyVisibleStubs) {
    311   FakeClient stub1(&memmgr_, GenerateUniqueSurfaceId(), true),
    312              stub2(&memmgr_, GenerateUniqueSurfaceId(), true),
    313              stub3(&memmgr_, GenerateUniqueSurfaceId(), true),
    314              stub4(&memmgr_, GenerateUniqueSurfaceId(), true);
    315 
    316   FakeClient stub5(&memmgr_ , &stub1), stub6(&memmgr_ , &stub2);
    317   FakeClient stub7(&memmgr_ , &stub2);
    318 
    319   Manage();
    320   EXPECT_TRUE(IsAllocationForegroundForSurfaceYes(stub1.allocation_));
    321   EXPECT_TRUE(IsAllocationForegroundForSurfaceYes(stub2.allocation_));
    322   EXPECT_TRUE(IsAllocationForegroundForSurfaceYes(stub3.allocation_));
    323   EXPECT_TRUE(IsAllocationForegroundForSurfaceYes(stub4.allocation_));
    324   EXPECT_TRUE(IsAllocationForegroundForSurfaceNo(stub5.allocation_));
    325   EXPECT_TRUE(IsAllocationForegroundForSurfaceNo(stub6.allocation_));
    326   EXPECT_TRUE(IsAllocationForegroundForSurfaceNo(stub7.allocation_));
    327 }
    328 
    329 // Test GpuMemoryManager::Manage functionality: Test more than threshold number
    330 // of not visible stubs.
    331 // Expect the stubs surpassing the threshold to not have a backbuffer.
    332 TEST_F(GpuMemoryManagerTest, TestManageManyNotVisibleStubs) {
    333   FakeClient stub1(&memmgr_, GenerateUniqueSurfaceId(), true),
    334              stub2(&memmgr_, GenerateUniqueSurfaceId(), true),
    335              stub3(&memmgr_, GenerateUniqueSurfaceId(), true),
    336              stub4(&memmgr_, GenerateUniqueSurfaceId(), true);
    337   stub4.SetVisible(false);
    338   stub3.SetVisible(false);
    339   stub2.SetVisible(false);
    340   stub1.SetVisible(false);
    341 
    342   FakeClient stub5(&memmgr_ , &stub1), stub6(&memmgr_ , &stub4);
    343   FakeClient stub7(&memmgr_ , &stub1);
    344 
    345   Manage();
    346   EXPECT_TRUE(IsAllocationBackgroundForSurfaceYes(stub1.allocation_));
    347   EXPECT_TRUE(IsAllocationBackgroundForSurfaceYes(stub2.allocation_));
    348   EXPECT_TRUE(IsAllocationBackgroundForSurfaceYes(stub3.allocation_));
    349   EXPECT_TRUE(IsAllocationHibernatedForSurfaceYes(stub4.allocation_));
    350   EXPECT_TRUE(IsAllocationBackgroundForSurfaceNo(stub5.allocation_));
    351   EXPECT_TRUE(IsAllocationHibernatedForSurfaceNo(stub6.allocation_));
    352   EXPECT_TRUE(IsAllocationBackgroundForSurfaceNo(stub7.allocation_));
    353 }
    354 
    355 // Test GpuMemoryManager::Manage functionality: Test changing the last used
    356 // time of stubs when doing so causes change in which stubs surpass threshold.
    357 // Expect frontbuffer to be dropped for the older stub.
    358 TEST_F(GpuMemoryManagerTest, TestManageChangingLastUsedTime) {
    359   FakeClient stub1(&memmgr_, GenerateUniqueSurfaceId(), true),
    360              stub2(&memmgr_, GenerateUniqueSurfaceId(), true),
    361              stub3(&memmgr_, GenerateUniqueSurfaceId(), true),
    362              stub4(&memmgr_, GenerateUniqueSurfaceId(), true);
    363 
    364   FakeClient stub5(&memmgr_ , &stub3), stub6(&memmgr_ , &stub4);
    365   FakeClient stub7(&memmgr_ , &stub3);
    366 
    367   // Make stub4 be the least-recently-used client
    368   stub4.SetVisible(false);
    369   stub3.SetVisible(false);
    370   stub2.SetVisible(false);
    371   stub1.SetVisible(false);
    372 
    373   Manage();
    374   EXPECT_TRUE(IsAllocationBackgroundForSurfaceYes(stub1.allocation_));
    375   EXPECT_TRUE(IsAllocationBackgroundForSurfaceYes(stub2.allocation_));
    376   EXPECT_TRUE(IsAllocationBackgroundForSurfaceYes(stub3.allocation_));
    377   EXPECT_TRUE(IsAllocationHibernatedForSurfaceYes(stub4.allocation_));
    378   EXPECT_TRUE(IsAllocationBackgroundForSurfaceNo(stub5.allocation_));
    379   EXPECT_TRUE(IsAllocationHibernatedForSurfaceNo(stub6.allocation_));
    380   EXPECT_TRUE(IsAllocationBackgroundForSurfaceNo(stub7.allocation_));
    381 
    382   // Make stub3 become the least-recently-used client.
    383   stub2.SetVisible(true);
    384   stub2.SetVisible(false);
    385   stub4.SetVisible(true);
    386   stub4.SetVisible(false);
    387 
    388   Manage();
    389   EXPECT_TRUE(IsAllocationBackgroundForSurfaceYes(stub1.allocation_));
    390   EXPECT_TRUE(IsAllocationBackgroundForSurfaceYes(stub2.allocation_));
    391   EXPECT_TRUE(IsAllocationHibernatedForSurfaceYes(stub3.allocation_));
    392   EXPECT_TRUE(IsAllocationBackgroundForSurfaceYes(stub4.allocation_));
    393   EXPECT_TRUE(IsAllocationHibernatedForSurfaceNo(stub5.allocation_));
    394   EXPECT_TRUE(IsAllocationBackgroundForSurfaceNo(stub6.allocation_));
    395   EXPECT_TRUE(IsAllocationHibernatedForSurfaceNo(stub7.allocation_));
    396 }
    397 
    398 // Test GpuMemoryManager::Manage functionality: Test changing importance of
    399 // enough stubs so that every stub in share group crosses threshold.
    400 // Expect memory allocation of the stubs without surface to share memory
    401 // allocation with the most visible stub in share group.
    402 TEST_F(GpuMemoryManagerTest, TestManageChangingImportanceShareGroup) {
    403   FakeClient stub_ignore_a(&memmgr_, GenerateUniqueSurfaceId(), true),
    404              stub_ignore_b(&memmgr_, GenerateUniqueSurfaceId(), false),
    405              stub_ignore_c(&memmgr_, GenerateUniqueSurfaceId(), false);
    406   FakeClient stub1(&memmgr_, GenerateUniqueSurfaceId(), false),
    407              stub2(&memmgr_, GenerateUniqueSurfaceId(), false);
    408 
    409   FakeClient stub3(&memmgr_, &stub2), stub4(&memmgr_, &stub2);
    410 
    411   // stub1 and stub2 keep their non-hibernated state because they're
    412   // either visible or the 2 most recently used clients (through the
    413   // first three checks).
    414   stub1.SetVisible(true);
    415   stub2.SetVisible(true);
    416   Manage();
    417   EXPECT_TRUE(IsAllocationForegroundForSurfaceYes(stub1.allocation_));
    418   EXPECT_TRUE(IsAllocationForegroundForSurfaceYes(stub2.allocation_));
    419   EXPECT_TRUE(IsAllocationForegroundForSurfaceNo(stub3.allocation_));
    420   EXPECT_TRUE(IsAllocationForegroundForSurfaceNo(stub4.allocation_));
    421 
    422   stub1.SetVisible(false);
    423   Manage();
    424   EXPECT_TRUE(IsAllocationBackgroundForSurfaceYes(stub1.allocation_));
    425   EXPECT_TRUE(IsAllocationForegroundForSurfaceYes(stub2.allocation_));
    426   EXPECT_TRUE(IsAllocationBackgroundForSurfaceNo(stub3.allocation_));
    427   EXPECT_TRUE(IsAllocationForegroundForSurfaceNo(stub4.allocation_));
    428 
    429   stub2.SetVisible(false);
    430   Manage();
    431   EXPECT_TRUE(IsAllocationBackgroundForSurfaceYes(stub1.allocation_));
    432   EXPECT_TRUE(IsAllocationBackgroundForSurfaceYes(stub2.allocation_));
    433   EXPECT_TRUE(IsAllocationBackgroundForSurfaceNo(stub3.allocation_));
    434   EXPECT_TRUE(IsAllocationBackgroundForSurfaceNo(stub4.allocation_));
    435 
    436   // stub_ignore_b will cause stub1 to become hibernated (because
    437   // stub_ignore_a, stub_ignore_b, and stub2 are all non-hibernated and more
    438   // important).
    439   stub_ignore_b.SetVisible(true);
    440   stub_ignore_b.SetVisible(false);
    441   Manage();
    442   EXPECT_TRUE(IsAllocationHibernatedForSurfaceYes(stub1.allocation_));
    443   EXPECT_TRUE(IsAllocationBackgroundForSurfaceYes(stub2.allocation_));
    444   EXPECT_TRUE(IsAllocationBackgroundForSurfaceNo(stub3.allocation_));
    445   EXPECT_TRUE(IsAllocationBackgroundForSurfaceNo(stub4.allocation_));
    446 
    447   // stub_ignore_c will cause stub2 to become hibernated (because
    448   // stub_ignore_a, stub_ignore_b, and stub_ignore_c are all non-hibernated
    449   // and more important).
    450   stub_ignore_c.SetVisible(true);
    451   stub_ignore_c.SetVisible(false);
    452   Manage();
    453   EXPECT_TRUE(IsAllocationHibernatedForSurfaceYes(stub1.allocation_));
    454   EXPECT_TRUE(IsAllocationHibernatedForSurfaceYes(stub2.allocation_));
    455   EXPECT_TRUE(IsAllocationHibernatedForSurfaceNo(stub3.allocation_));
    456   EXPECT_TRUE(IsAllocationHibernatedForSurfaceNo(stub4.allocation_));
    457 }
    458 
    459 // Test GpuMemoryManager::UpdateAvailableGpuMemory functionality
    460 TEST_F(GpuMemoryManagerTest, TestUpdateAvailableGpuMemory) {
    461   FakeClient stub1(&memmgr_, GenerateUniqueSurfaceId(), true),
    462              stub2(&memmgr_, GenerateUniqueSurfaceId(), false),
    463              stub3(&memmgr_, GenerateUniqueSurfaceId(), true),
    464              stub4(&memmgr_, GenerateUniqueSurfaceId(), false);
    465   // We take the lowest GPU's total memory as the limit
    466   uint64 expected = 400 * 1024 * 1024;
    467   stub1.SetTotalGpuMemory(expected); // GPU Memory
    468   stub2.SetTotalGpuMemory(expected - 1024 * 1024); // Smaller but not visible.
    469   stub3.SetTotalGpuMemory(expected + 1024 * 1024); // Visible but larger.
    470   stub4.SetTotalGpuMemory(expected + 1024 * 1024); // Not visible and larger.
    471   Manage();
    472   uint64 bytes_expected = CalcAvailableFromGpuTotal(expected);
    473   EXPECT_EQ(GetAvailableGpuMemory(), CalcAvailableClamped(bytes_expected));
    474 }
    475 
    476 
    477 // Test GpuMemoryAllocation comparison operators: Iterate over all possible
    478 // combinations of gpu_resource_size_in_bytes, suggest_have_backbuffer, and
    479 // suggest_have_frontbuffer, and make sure allocations with equal values test
    480 // equal and non equal values test not equal.
    481 TEST_F(GpuMemoryManagerTest, GpuMemoryAllocationCompareTests) {
    482   std::vector<int> gpu_resource_size_in_bytes_values;
    483   gpu_resource_size_in_bytes_values.push_back(0);
    484   gpu_resource_size_in_bytes_values.push_back(1);
    485   gpu_resource_size_in_bytes_values.push_back(12345678);
    486 
    487   std::vector<GpuMemoryAllocation::BufferAllocation>
    488       suggested_buffer_allocation_values;
    489   suggested_buffer_allocation_values.push_back(
    490       GpuMemoryAllocation::kHasFrontbuffer);
    491   suggested_buffer_allocation_values.push_back(
    492       GpuMemoryAllocation::kHasFrontbuffer);
    493   suggested_buffer_allocation_values.push_back(
    494       GpuMemoryAllocation::kHasNoFrontbuffer);
    495   suggested_buffer_allocation_values.push_back(
    496       GpuMemoryAllocation::kHasNoFrontbuffer);
    497 
    498   for (size_t i = 0; i != gpu_resource_size_in_bytes_values.size(); ++i) {
    499     for (size_t j = 0; j != suggested_buffer_allocation_values.size(); ++j) {
    500       uint64 sz = gpu_resource_size_in_bytes_values[i];
    501       GpuMemoryAllocation::BufferAllocation buffer_allocation =
    502           suggested_buffer_allocation_values[j];
    503       GpuMemoryAllocation allocation(sz, buffer_allocation);
    504 
    505       EXPECT_TRUE(allocation.Equals(
    506           GpuMemoryAllocation(sz, buffer_allocation)));
    507       EXPECT_FALSE(allocation.Equals(
    508           GpuMemoryAllocation(sz+1, buffer_allocation)));
    509 
    510       for (size_t k = 0; k != suggested_buffer_allocation_values.size(); ++k) {
    511         GpuMemoryAllocation::BufferAllocation buffer_allocation_other =
    512             suggested_buffer_allocation_values[k];
    513         if (buffer_allocation == buffer_allocation_other) continue;
    514         EXPECT_FALSE(allocation.Equals(
    515             GpuMemoryAllocation(sz, buffer_allocation_other)));
    516       }
    517     }
    518   }
    519 }
    520 
    521 // Test GpuMemoryManager Stub Memory Stats functionality:
    522 // Creates various surface/non-surface stubs and switches stub visibility and
    523 // tests to see that stats data structure values are correct.
    524 TEST_F(GpuMemoryManagerTest, StubMemoryStatsForLastManageTests) {
    525   ClientAssignmentCollector::ClientMemoryStatMap stats;
    526 
    527   Manage();
    528   stats = ClientAssignmentCollector::GetClientStatsForLastManage();
    529   EXPECT_EQ(stats.size(), 0ul);
    530 
    531   FakeClient stub1(&memmgr_, GenerateUniqueSurfaceId(), true);
    532   Manage();
    533   stats = ClientAssignmentCollector::GetClientStatsForLastManage();
    534   uint64 stub1allocation1 =
    535       stats[&stub1].allocation.renderer_allocation.bytes_limit_when_visible;
    536 
    537   EXPECT_EQ(stats.size(), 1ul);
    538   EXPECT_GT(stub1allocation1, 0ul);
    539 
    540   FakeClient stub2(&memmgr_, &stub1);
    541   Manage();
    542   stats = ClientAssignmentCollector::GetClientStatsForLastManage();
    543   EXPECT_EQ(stats.count(&stub1), 1ul);
    544   uint64 stub1allocation2 =
    545       stats[&stub1].allocation.renderer_allocation.bytes_limit_when_visible;
    546   EXPECT_EQ(stats.count(&stub2), 1ul);
    547   uint64 stub2allocation2 =
    548       stats[&stub2].allocation.renderer_allocation.bytes_limit_when_visible;
    549 
    550   EXPECT_EQ(stats.size(), 2ul);
    551   EXPECT_GT(stub1allocation2, 0ul);
    552   EXPECT_GT(stub2allocation2, 0ul);
    553   if (stub1allocation2 != GetMaximumClientAllocation())
    554     EXPECT_LT(stub1allocation2, stub1allocation1);
    555 
    556   FakeClient stub3(&memmgr_, GenerateUniqueSurfaceId(), true);
    557   Manage();
    558   stats = ClientAssignmentCollector::GetClientStatsForLastManage();
    559   uint64 stub1allocation3 =
    560       stats[&stub1].allocation.renderer_allocation.bytes_limit_when_visible;
    561   uint64 stub2allocation3 =
    562       stats[&stub2].allocation.renderer_allocation.bytes_limit_when_visible;
    563   uint64 stub3allocation3 =
    564       stats[&stub3].allocation.renderer_allocation.bytes_limit_when_visible;
    565 
    566   EXPECT_EQ(stats.size(), 3ul);
    567   EXPECT_GT(stub1allocation3, 0ul);
    568   EXPECT_GT(stub2allocation3, 0ul);
    569   EXPECT_GT(stub3allocation3, 0ul);
    570   if (stub1allocation3 != GetMaximumClientAllocation())
    571     EXPECT_LT(stub1allocation3, stub1allocation2);
    572 
    573   stub1.SetVisible(false);
    574 
    575   Manage();
    576   stats = ClientAssignmentCollector::GetClientStatsForLastManage();
    577   uint64 stub1allocation4 =
    578       stats[&stub1].allocation.renderer_allocation.bytes_limit_when_visible;
    579   uint64 stub2allocation4 =
    580       stats[&stub2].allocation.renderer_allocation.bytes_limit_when_visible;
    581   uint64 stub3allocation4 =
    582       stats[&stub3].allocation.renderer_allocation.bytes_limit_when_visible;
    583 
    584   EXPECT_EQ(stats.size(), 3ul);
    585   EXPECT_GT(stub1allocation4, 0ul);
    586   EXPECT_GE(stub2allocation4, 0ul);
    587   EXPECT_GT(stub3allocation4, 0ul);
    588   if (stub3allocation3 != GetMaximumClientAllocation())
    589     EXPECT_GT(stub3allocation4, stub3allocation3);
    590 }
    591 
    592 // Test GpuMemoryManager's managed memory tracking
    593 TEST_F(GpuMemoryManagerTest, TestManagedUsageTracking) {
    594   FakeClient stub1(&memmgr_, GenerateUniqueSurfaceId(), true),
    595              stub2(&memmgr_, GenerateUniqueSurfaceId(), false);
    596   EXPECT_EQ(0ul, memmgr_.bytes_allocated_managed_visible_);
    597   EXPECT_EQ(0ul, memmgr_.bytes_allocated_managed_nonvisible_);
    598 
    599   // Set memory allocations and verify the results are reflected.
    600   stub1.SetManagedMemoryStats(GpuManagedMemoryStats(0, 0, 5, false));
    601   stub2.SetManagedMemoryStats(GpuManagedMemoryStats(0, 0, 7, false));
    602   EXPECT_EQ(5ul, memmgr_.bytes_allocated_managed_visible_);
    603   EXPECT_EQ(7ul, memmgr_.bytes_allocated_managed_nonvisible_);
    604 
    605   // Remove a visible client
    606   stub1.client_state_.reset();
    607   EXPECT_EQ(0ul, memmgr_.bytes_allocated_managed_visible_);
    608   EXPECT_EQ(7ul, memmgr_.bytes_allocated_managed_nonvisible_);
    609   EXPECT_EQ(0ul, memmgr_.bytes_allocated_managed_visible_);
    610   EXPECT_EQ(7ul, memmgr_.bytes_allocated_managed_nonvisible_);
    611   stub1.client_state_.reset(memmgr_.CreateClientState(&stub1, true, true));
    612   EXPECT_EQ(0ul, memmgr_.bytes_allocated_managed_visible_);
    613   EXPECT_EQ(7ul, memmgr_.bytes_allocated_managed_nonvisible_);
    614   stub1.SetManagedMemoryStats(GpuManagedMemoryStats(0, 0, 5, false));
    615   EXPECT_EQ(5ul, memmgr_.bytes_allocated_managed_visible_);
    616   EXPECT_EQ(7ul, memmgr_.bytes_allocated_managed_nonvisible_);
    617 
    618   // Remove a nonvisible client
    619   stub2.client_state_.reset();
    620   EXPECT_EQ(5ul, memmgr_.bytes_allocated_managed_visible_);
    621   EXPECT_EQ(0ul, memmgr_.bytes_allocated_managed_nonvisible_);
    622   EXPECT_EQ(5ul, memmgr_.bytes_allocated_managed_visible_);
    623   EXPECT_EQ(0ul, memmgr_.bytes_allocated_managed_nonvisible_);
    624   stub2.client_state_.reset(memmgr_.CreateClientState(&stub2, true, false));
    625   EXPECT_EQ(5ul, memmgr_.bytes_allocated_managed_visible_);
    626   EXPECT_EQ(0ul, memmgr_.bytes_allocated_managed_nonvisible_);
    627   stub2.SetManagedMemoryStats(GpuManagedMemoryStats(0, 0, 7, false));
    628   EXPECT_EQ(5ul, memmgr_.bytes_allocated_managed_visible_);
    629   EXPECT_EQ(7ul, memmgr_.bytes_allocated_managed_nonvisible_);
    630 
    631   // Create and then destroy some stubs, and verify their allocations go away.
    632   {
    633     FakeClient stub3(&memmgr_, GenerateUniqueSurfaceId(), true),
    634                stub4(&memmgr_, GenerateUniqueSurfaceId(), false);
    635     stub3.SetManagedMemoryStats(GpuManagedMemoryStats(0, 0, 1, false));
    636     stub4.SetManagedMemoryStats(GpuManagedMemoryStats(0, 0, 2, false));
    637     EXPECT_EQ(6ul, memmgr_.bytes_allocated_managed_visible_);
    638     EXPECT_EQ(9ul, memmgr_.bytes_allocated_managed_nonvisible_);
    639   }
    640   EXPECT_EQ(5ul, memmgr_.bytes_allocated_managed_visible_);
    641   EXPECT_EQ(7ul, memmgr_.bytes_allocated_managed_nonvisible_);
    642 
    643   // Do no-op changes to stubs' visibility and make sure nothing chnages.
    644   stub1.SetVisible(true);
    645   stub2.SetVisible(false);
    646   EXPECT_EQ(5ul, memmgr_.bytes_allocated_managed_visible_);
    647   EXPECT_EQ(7ul, memmgr_.bytes_allocated_managed_nonvisible_);
    648 
    649   // Change visbility state.
    650   stub1.SetVisible(false);
    651   stub2.SetVisible(true);
    652   EXPECT_EQ(7ul, memmgr_.bytes_allocated_managed_visible_);
    653   EXPECT_EQ(5ul, memmgr_.bytes_allocated_managed_nonvisible_);
    654 
    655   // Increase allocation amounts.
    656   stub1.SetManagedMemoryStats(GpuManagedMemoryStats(0, 0, 6, false));
    657   stub2.SetManagedMemoryStats(GpuManagedMemoryStats(0, 0, 8, false));
    658   EXPECT_EQ(8ul, memmgr_.bytes_allocated_managed_visible_);
    659   EXPECT_EQ(6ul, memmgr_.bytes_allocated_managed_nonvisible_);
    660 
    661   // Decrease allocation amounts.
    662   stub1.SetManagedMemoryStats(GpuManagedMemoryStats(0, 0, 4, false));
    663   stub2.SetManagedMemoryStats(GpuManagedMemoryStats(0, 0, 6, false));
    664   EXPECT_EQ(6ul, memmgr_.bytes_allocated_managed_visible_);
    665   EXPECT_EQ(4ul, memmgr_.bytes_allocated_managed_nonvisible_);
    666 }
    667 
    668 // Test nonvisible MRU behavior (the most recently used nonvisible clients
    669 // keep their contents).
    670 TEST_F(GpuMemoryManagerTest, BackgroundMru) {
    671   // Set memory manager constants for this test. Note that the budget
    672   // for backgrounded content will be 64/4 = 16.
    673   memmgr_.TestingSetAvailableGpuMemory(64);
    674   memmgr_.TestingSetMinimumClientAllocation(8);
    675 
    676   uint64 bytes_when_not_visible_expected = 6u;
    677   if (!memmgr_.allow_nonvisible_memory_)
    678     bytes_when_not_visible_expected = 0;
    679 
    680   FakeClient stub1(&memmgr_, GenerateUniqueSurfaceId(), true);
    681   FakeClient stub2(&memmgr_, GenerateUniqueSurfaceId(), true);
    682   FakeClient stub3(&memmgr_, GenerateUniqueSurfaceId(), true);
    683 
    684   // When all are visible, they should all be allowed to have memory
    685   // should they become nonvisible.
    686   SetClientStats(&stub1, 6, 23);
    687   SetClientStats(&stub2, 6, 23);
    688   SetClientStats(&stub3, 6, 23);
    689   Manage();
    690   EXPECT_GE(stub1.BytesWhenVisible(), 20u);
    691   EXPECT_GE(stub2.BytesWhenVisible(), 20u);
    692   EXPECT_GE(stub3.BytesWhenVisible(), 20u);
    693   EXPECT_LT(stub1.BytesWhenVisible(), 22u);
    694   EXPECT_LT(stub2.BytesWhenVisible(), 22u);
    695   EXPECT_LT(stub3.BytesWhenVisible(), 22u);
    696   EXPECT_GE(stub1.BytesWhenNotVisible(), bytes_when_not_visible_expected);
    697   EXPECT_GE(stub2.BytesWhenNotVisible(), bytes_when_not_visible_expected);
    698   EXPECT_GE(stub3.BytesWhenNotVisible(), bytes_when_not_visible_expected);
    699 
    700   // Background stubs 1 and 2, and they should fit. All stubs should
    701   // have their full nicetohave budget should they become visible.
    702   stub2.SetVisible(false);
    703   stub1.SetVisible(false);
    704   Manage();
    705   EXPECT_GE(stub1.BytesWhenVisible(), 23u);
    706   EXPECT_GE(stub2.BytesWhenVisible(), 23u);
    707   EXPECT_GE(stub3.BytesWhenVisible(), 23u);
    708   EXPECT_LT(stub1.BytesWhenVisible(), 32u);
    709   EXPECT_LT(stub2.BytesWhenVisible(), 32u);
    710   EXPECT_GE(stub1.BytesWhenNotVisible(), bytes_when_not_visible_expected);
    711   EXPECT_GE(stub2.BytesWhenNotVisible(), bytes_when_not_visible_expected);
    712   EXPECT_GE(stub3.BytesWhenNotVisible(), bytes_when_not_visible_expected);
    713 
    714   // Now background stub 3, and it should cause stub 2 to be
    715   // evicted because it was set non-visible first
    716   stub3.SetVisible(false);
    717   Manage();
    718   EXPECT_GE(stub1.BytesWhenNotVisible(), bytes_when_not_visible_expected);
    719   EXPECT_EQ(stub2.BytesWhenNotVisible(), 0u);
    720   EXPECT_GE(stub3.BytesWhenNotVisible(), bytes_when_not_visible_expected);
    721 }
    722 
    723 // Test that once a backgrounded client has dropped its resources, it
    724 // doesn't get them back until it becomes visible again.
    725 TEST_F(GpuMemoryManagerTest, BackgroundDiscardPersistent) {
    726   // Set memory manager constants for this test. Note that the budget
    727   // for backgrounded content will be 64/4 = 16.
    728   memmgr_.TestingSetAvailableGpuMemory(64);
    729   memmgr_.TestingSetMinimumClientAllocation(8);
    730 
    731   uint64 bytes_when_not_visible_expected = 10ul;
    732   if (!memmgr_.allow_nonvisible_memory_)
    733     bytes_when_not_visible_expected = 0;
    734 
    735   FakeClient stub1(&memmgr_, GenerateUniqueSurfaceId(), true);
    736   FakeClient stub2(&memmgr_, GenerateUniqueSurfaceId(), true);
    737 
    738   // Both clients should be able to keep their contents should one of
    739   // them become nonvisible.
    740   SetClientStats(&stub1, 10, 20);
    741   SetClientStats(&stub2, 10, 20);
    742   Manage();
    743   EXPECT_GE(stub1.BytesWhenNotVisible(), bytes_when_not_visible_expected);
    744   EXPECT_GE(stub2.BytesWhenNotVisible(), bytes_when_not_visible_expected);
    745 
    746   // If they both go nonvisible, then only the most recently used client
    747   // should keep its contents.
    748   stub1.SetVisible(false);
    749   stub2.SetVisible(false);
    750   Manage();
    751   EXPECT_EQ(stub1.BytesWhenNotVisible(), 0u);
    752   EXPECT_GE(stub2.BytesWhenNotVisible(), bytes_when_not_visible_expected);
    753 
    754   // When becoming visible, stub 2 should get its contents back, and
    755   // retain them next time it is made nonvisible.
    756   stub2.SetVisible(true);
    757   Manage();
    758   EXPECT_GE(stub2.BytesWhenNotVisible(), bytes_when_not_visible_expected);
    759   stub2.SetVisible(false);
    760   Manage();
    761   EXPECT_GE(stub2.BytesWhenNotVisible(), bytes_when_not_visible_expected);
    762 }
    763 
    764 // Test tracking of unmanaged (e.g, WebGL) memory.
    765 TEST_F(GpuMemoryManagerTest, UnmanagedTracking) {
    766   // Set memory manager constants for this test
    767   memmgr_.TestingSetAvailableGpuMemory(64);
    768   memmgr_.TestingSetMinimumClientAllocation(8);
    769   memmgr_.TestingSetUnmanagedLimitStep(16);
    770 
    771   FakeClient stub1(&memmgr_, GenerateUniqueSurfaceId(), true);
    772 
    773   // Expect that the one stub get its nicetohave level.
    774   SetClientStats(&stub1, 16, 32);
    775   Manage();
    776   EXPECT_GE(stub1.BytesWhenVisible(), 32u);
    777 
    778   // Now allocate some unmanaged memory and make sure the amount
    779   // goes down.
    780   memmgr_.TrackMemoryAllocatedChange(
    781       stub1.tracking_group_.get(),
    782       0,
    783       48,
    784       gpu::gles2::MemoryTracker::kUnmanaged);
    785   Manage();
    786   EXPECT_LT(stub1.BytesWhenVisible(), 24u);
    787 
    788   // Now allocate the entire FB worth of unmanaged memory, and
    789   // make sure that we stay stuck at the minimum tab allocation.
    790   memmgr_.TrackMemoryAllocatedChange(
    791       stub1.tracking_group_.get(),
    792       48,
    793       64,
    794       gpu::gles2::MemoryTracker::kUnmanaged);
    795   Manage();
    796   EXPECT_EQ(stub1.BytesWhenVisible(), 8u);
    797 
    798   // Far-oversubscribe the entire FB, and make sure we stay at
    799   // the minimum allocation, and don't blow up.
    800   memmgr_.TrackMemoryAllocatedChange(
    801       stub1.tracking_group_.get(),
    802       64,
    803       999,
    804       gpu::gles2::MemoryTracker::kUnmanaged);
    805   Manage();
    806   EXPECT_EQ(stub1.BytesWhenVisible(), 8u);
    807 
    808   // Delete all tracked memory so we don't hit leak checks.
    809   memmgr_.TrackMemoryAllocatedChange(
    810       stub1.tracking_group_.get(),
    811       999,
    812       0,
    813       gpu::gles2::MemoryTracker::kUnmanaged);
    814 }
    815 
    816 // Test the default allocation levels are used.
    817 TEST_F(GpuMemoryManagerTest, DefaultAllocation) {
    818   // Set memory manager constants for this test
    819   memmgr_.TestingSetAvailableGpuMemory(64);
    820   memmgr_.TestingSetMinimumClientAllocation(8);
    821   memmgr_.TestingSetDefaultClientAllocation(16);
    822 
    823   FakeClient stub1(&memmgr_, GenerateUniqueSurfaceId(), true);
    824 
    825   // Expect that a client which has not sent stats receive at
    826   // least the default allocation.
    827   Manage();
    828   EXPECT_GE(stub1.BytesWhenVisible(),
    829             memmgr_.GetDefaultClientAllocation());
    830   EXPECT_EQ(stub1.BytesWhenNotVisible(), 0u);
    831 }
    832 
    833 }  // namespace content
    834