// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "content/common/gpu/gpu_memory_manager.h"

#include "content/common/gpu/gpu_memory_manager_client.h"
#include "content/common/gpu/gpu_memory_tracking.h"
#include "gpu/command_buffer/common/gpu_memory_allocation.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "ui/gfx/geometry/size_conversions.h"

using gpu::MemoryAllocation;

class FakeMemoryTracker : public gpu::gles2::MemoryTracker {
 public:
  void TrackMemoryAllocatedChange(
      size_t /* old_size */,
      size_t /* new_size */,
      gpu::gles2::MemoryTracker::Pool /* pool */) override {}
  bool EnsureGPUMemoryAvailable(size_t /* size_needed */) override {
    return true;
  }
 private:
  ~FakeMemoryTracker() override {}
};

namespace content {

// This class is used to collect all stub assignments during a
// Manage() call.
class ClientAssignmentCollector {
 public:
  struct ClientMemoryStat {
    MemoryAllocation allocation;
  };
  typedef base::hash_map<GpuMemoryManagerClient*, ClientMemoryStat>
      ClientMemoryStatMap;

  static const ClientMemoryStatMap& GetClientStatsForLastManage() {
    return client_memory_stats_for_last_manage_;
  }
  static void ClearAllStats() {
    client_memory_stats_for_last_manage_.clear();
  }
  static void AddClientStat(GpuMemoryManagerClient* client,
                          const MemoryAllocation& allocation) {
    DCHECK(!client_memory_stats_for_last_manage_.count(client));
    client_memory_stats_for_last_manage_[client].allocation = allocation;
  }

 private:
  static ClientMemoryStatMap client_memory_stats_for_last_manage_;
};

ClientAssignmentCollector::ClientMemoryStatMap
    ClientAssignmentCollector::client_memory_stats_for_last_manage_;

class FakeClient : public GpuMemoryManagerClient {
 public:
  GpuMemoryManager* memmgr_;
  bool suggest_have_frontbuffer_;
  MemoryAllocation allocation_;
  uint64 total_gpu_memory_;
  gfx::Size surface_size_;
  GpuMemoryManagerClient* share_group_;
  scoped_refptr<gpu::gles2::MemoryTracker> memory_tracker_;
  scoped_ptr<GpuMemoryTrackingGroup> tracking_group_;
  scoped_ptr<GpuMemoryManagerClientState> client_state_;

  // This will create a client with no surface
  FakeClient(GpuMemoryManager* memmgr, GpuMemoryManagerClient* share_group)
      : memmgr_(memmgr),
        suggest_have_frontbuffer_(false),
        total_gpu_memory_(0),
        share_group_(share_group),
        memory_tracker_(NULL) {
    if (!share_group_) {
      memory_tracker_ = new FakeMemoryTracker();
      tracking_group_.reset(
          memmgr_->CreateTrackingGroup(0, memory_tracker_.get()));
    }
    client_state_.reset(memmgr_->CreateClientState(this, false, true));
  }

  // This will create a client with a surface
  FakeClient(GpuMemoryManager* memmgr, int32 surface_id, bool visible)
      : memmgr_(memmgr),
        suggest_have_frontbuffer_(false),
        total_gpu_memory_(0),
        share_group_(NULL),
        memory_tracker_(NULL) {
    memory_tracker_ = new FakeMemoryTracker();
    tracking_group_.reset(
        memmgr_->CreateTrackingGroup(0, memory_tracker_.get()));
    client_state_.reset(
        memmgr_->CreateClientState(this, surface_id != 0, visible));
  }

  ~FakeClient() override {
    client_state_.reset();
    tracking_group_.reset();
    memory_tracker_ = NULL;
  }

  void SetMemoryAllocation(const MemoryAllocation& alloc) override {
    allocation_ = alloc;
    ClientAssignmentCollector::AddClientStat(this, alloc);
  }

  void SuggestHaveFrontBuffer(bool suggest_have_frontbuffer) override {
    suggest_have_frontbuffer_ = suggest_have_frontbuffer;
  }

  bool GetTotalGpuMemory(uint64* bytes) override {
    if (total_gpu_memory_) {
      *bytes = total_gpu_memory_;
      return true;
    }
    return false;
  }
  void SetTotalGpuMemory(uint64 bytes) { total_gpu_memory_ = bytes; }

  gpu::gles2::MemoryTracker* GetMemoryTracker() const override {
    if (share_group_)
      return share_group_->GetMemoryTracker();
    return memory_tracker_.get();
  }

  gfx::Size GetSurfaceSize() const override { return surface_size_; }
  void SetSurfaceSize(gfx::Size size) { surface_size_ = size; }

  void SetVisible(bool visible) {
    client_state_->SetVisible(visible);
  }

  uint64 BytesWhenVisible() const {
    return allocation_.bytes_limit_when_visible;
  }
};

class GpuMemoryManagerTest : public testing::Test {
 protected:
  static const uint64 kFrontbufferLimitForTest = 3;

  GpuMemoryManagerTest()
      : memmgr_(0, kFrontbufferLimitForTest) {
    memmgr_.TestingDisableScheduleManage();
  }

  void SetUp() override {}

  static int32 GenerateUniqueSurfaceId() {
    static int32 surface_id_ = 1;
    return surface_id_++;
  }

  bool IsAllocationForegroundForSurfaceYes(
      const MemoryAllocation& alloc) {
    return true;
  }
  bool IsAllocationBackgroundForSurfaceYes(
      const MemoryAllocation& alloc) {
    return true;
  }
  bool IsAllocationHibernatedForSurfaceYes(
      const MemoryAllocation& alloc) {
    return true;
  }
  bool IsAllocationForegroundForSurfaceNo(
      const MemoryAllocation& alloc) {
    return alloc.bytes_limit_when_visible != 0;
  }
  bool IsAllocationBackgroundForSurfaceNo(
      const MemoryAllocation& alloc) {
    return alloc.bytes_limit_when_visible != 0;
  }
  bool IsAllocationHibernatedForSurfaceNo(
      const MemoryAllocation& alloc) {
    return alloc.bytes_limit_when_visible == 0;
  }

  void Manage() {
    ClientAssignmentCollector::ClearAllStats();
    memmgr_.Manage();
  }

  GpuMemoryManager memmgr_;
};

// Test GpuMemoryManager::Manage basic functionality.
// Expect memory allocation to set suggest_have_frontbuffer/backbuffer
// according to visibility and last used time for stubs with surface.
// Expect memory allocation to be shared according to share groups for stubs
// without a surface.
TEST_F(GpuMemoryManagerTest, TestManageBasicFunctionality) {
  // Test stubs with surface.
  FakeClient stub1(&memmgr_, GenerateUniqueSurfaceId(), true),
             stub2(&memmgr_, GenerateUniqueSurfaceId(), false);

  Manage();
  EXPECT_TRUE(IsAllocationForegroundForSurfaceYes(stub1.allocation_));
  EXPECT_TRUE(IsAllocationBackgroundForSurfaceYes(stub2.allocation_));

  // Test stubs without surface, with share group of 1 stub.
  FakeClient stub3(&memmgr_, &stub1), stub4(&memmgr_, &stub2);

  Manage();
  EXPECT_TRUE(IsAllocationForegroundForSurfaceYes(stub1.allocation_));
  EXPECT_TRUE(IsAllocationBackgroundForSurfaceYes(stub2.allocation_));
  EXPECT_TRUE(IsAllocationForegroundForSurfaceNo(stub3.allocation_));
  EXPECT_TRUE(IsAllocationBackgroundForSurfaceNo(stub4.allocation_));

  // Test stub without surface, with share group of multiple stubs.
  FakeClient stub5(&memmgr_ , &stub2);

  Manage();
  EXPECT_TRUE(IsAllocationForegroundForSurfaceNo(stub4.allocation_));
}

// Test GpuMemoryManager::Manage functionality: changing visibility.
// Expect memory allocation to set suggest_have_frontbuffer/backbuffer
// according to visibility and last used time for stubs with surface.
// Expect memory allocation to be shared according to share groups for stubs
// without a surface.
TEST_F(GpuMemoryManagerTest, TestManageChangingVisibility) {
  FakeClient stub1(&memmgr_, GenerateUniqueSurfaceId(), true),
             stub2(&memmgr_, GenerateUniqueSurfaceId(), false);

  FakeClient stub3(&memmgr_, &stub1), stub4(&memmgr_, &stub2);
  FakeClient stub5(&memmgr_ , &stub2);

  Manage();
  EXPECT_TRUE(IsAllocationForegroundForSurfaceYes(stub1.allocation_));
  EXPECT_TRUE(IsAllocationBackgroundForSurfaceYes(stub2.allocation_));
  EXPECT_TRUE(IsAllocationForegroundForSurfaceNo(stub3.allocation_));
  EXPECT_TRUE(IsAllocationBackgroundForSurfaceNo(stub4.allocation_));
  EXPECT_TRUE(IsAllocationForegroundForSurfaceNo(stub5.allocation_));

  stub1.SetVisible(false);
  stub2.SetVisible(true);

  Manage();
  EXPECT_TRUE(IsAllocationBackgroundForSurfaceYes(stub1.allocation_));
  EXPECT_TRUE(IsAllocationForegroundForSurfaceYes(stub2.allocation_));
  EXPECT_TRUE(IsAllocationBackgroundForSurfaceNo(stub3.allocation_));
  EXPECT_TRUE(IsAllocationForegroundForSurfaceNo(stub4.allocation_));
  EXPECT_TRUE(IsAllocationForegroundForSurfaceNo(stub5.allocation_));
}

// Test GpuMemoryManager::Manage functionality: Test more than threshold number
// of visible stubs.
// Expect all allocations to continue to have frontbuffer.
TEST_F(GpuMemoryManagerTest, TestManageManyVisibleStubs) {
  FakeClient stub1(&memmgr_, GenerateUniqueSurfaceId(), true),
             stub2(&memmgr_, GenerateUniqueSurfaceId(), true),
             stub3(&memmgr_, GenerateUniqueSurfaceId(), true),
             stub4(&memmgr_, GenerateUniqueSurfaceId(), true);

  FakeClient stub5(&memmgr_ , &stub1), stub6(&memmgr_ , &stub2);
  FakeClient stub7(&memmgr_ , &stub2);

  Manage();
  EXPECT_TRUE(IsAllocationForegroundForSurfaceYes(stub1.allocation_));
  EXPECT_TRUE(IsAllocationForegroundForSurfaceYes(stub2.allocation_));
  EXPECT_TRUE(IsAllocationForegroundForSurfaceYes(stub3.allocation_));
  EXPECT_TRUE(IsAllocationForegroundForSurfaceYes(stub4.allocation_));
  EXPECT_TRUE(IsAllocationForegroundForSurfaceNo(stub5.allocation_));
  EXPECT_TRUE(IsAllocationForegroundForSurfaceNo(stub6.allocation_));
  EXPECT_TRUE(IsAllocationForegroundForSurfaceNo(stub7.allocation_));
}

// Test GpuMemoryManager::Manage functionality: Test more than threshold number
// of not visible stubs.
// Expect the stubs surpassing the threshold to not have a backbuffer.
TEST_F(GpuMemoryManagerTest, TestManageManyNotVisibleStubs) {
  FakeClient stub1(&memmgr_, GenerateUniqueSurfaceId(), true),
             stub2(&memmgr_, GenerateUniqueSurfaceId(), true),
             stub3(&memmgr_, GenerateUniqueSurfaceId(), true),
             stub4(&memmgr_, GenerateUniqueSurfaceId(), true);
  stub4.SetVisible(false);
  stub3.SetVisible(false);
  stub2.SetVisible(false);
  stub1.SetVisible(false);

  FakeClient stub5(&memmgr_ , &stub1), stub6(&memmgr_ , &stub4);
  FakeClient stub7(&memmgr_ , &stub1);

  Manage();
  EXPECT_TRUE(IsAllocationBackgroundForSurfaceYes(stub1.allocation_));
  EXPECT_TRUE(IsAllocationBackgroundForSurfaceYes(stub2.allocation_));
  EXPECT_TRUE(IsAllocationBackgroundForSurfaceYes(stub3.allocation_));
  EXPECT_TRUE(IsAllocationHibernatedForSurfaceYes(stub4.allocation_));
  EXPECT_TRUE(IsAllocationBackgroundForSurfaceNo(stub5.allocation_));
  EXPECT_TRUE(IsAllocationHibernatedForSurfaceNo(stub6.allocation_));
  EXPECT_TRUE(IsAllocationBackgroundForSurfaceNo(stub7.allocation_));
}

// Test GpuMemoryManager::Manage functionality: Test changing the last used
// time of stubs when doing so causes change in which stubs surpass threshold.
// Expect frontbuffer to be dropped for the older stub.
TEST_F(GpuMemoryManagerTest, TestManageChangingLastUsedTime) {
  FakeClient stub1(&memmgr_, GenerateUniqueSurfaceId(), true),
             stub2(&memmgr_, GenerateUniqueSurfaceId(), true),
             stub3(&memmgr_, GenerateUniqueSurfaceId(), true),
             stub4(&memmgr_, GenerateUniqueSurfaceId(), true);

  FakeClient stub5(&memmgr_ , &stub3), stub6(&memmgr_ , &stub4);
  FakeClient stub7(&memmgr_ , &stub3);

  // Make stub4 be the least-recently-used client
  stub4.SetVisible(false);
  stub3.SetVisible(false);
  stub2.SetVisible(false);
  stub1.SetVisible(false);

  Manage();
  EXPECT_TRUE(IsAllocationBackgroundForSurfaceYes(stub1.allocation_));
  EXPECT_TRUE(IsAllocationBackgroundForSurfaceYes(stub2.allocation_));
  EXPECT_TRUE(IsAllocationBackgroundForSurfaceYes(stub3.allocation_));
  EXPECT_TRUE(IsAllocationHibernatedForSurfaceYes(stub4.allocation_));
  EXPECT_TRUE(IsAllocationBackgroundForSurfaceNo(stub5.allocation_));
  EXPECT_TRUE(IsAllocationHibernatedForSurfaceNo(stub6.allocation_));
  EXPECT_TRUE(IsAllocationBackgroundForSurfaceNo(stub7.allocation_));

  // Make stub3 become the least-recently-used client.
  stub2.SetVisible(true);
  stub2.SetVisible(false);
  stub4.SetVisible(true);
  stub4.SetVisible(false);

  Manage();
  EXPECT_TRUE(IsAllocationBackgroundForSurfaceYes(stub1.allocation_));
  EXPECT_TRUE(IsAllocationBackgroundForSurfaceYes(stub2.allocation_));
  EXPECT_TRUE(IsAllocationHibernatedForSurfaceYes(stub3.allocation_));
  EXPECT_TRUE(IsAllocationBackgroundForSurfaceYes(stub4.allocation_));
  EXPECT_TRUE(IsAllocationHibernatedForSurfaceNo(stub5.allocation_));
  EXPECT_TRUE(IsAllocationBackgroundForSurfaceNo(stub6.allocation_));
  EXPECT_TRUE(IsAllocationHibernatedForSurfaceNo(stub7.allocation_));
}

// Test GpuMemoryManager::Manage functionality: Test changing importance of
// enough stubs so that every stub in share group crosses threshold.
// Expect memory allocation of the stubs without surface to share memory
// allocation with the most visible stub in share group.
TEST_F(GpuMemoryManagerTest, TestManageChangingImportanceShareGroup) {
  FakeClient stub_ignore_a(&memmgr_, GenerateUniqueSurfaceId(), true),
             stub_ignore_b(&memmgr_, GenerateUniqueSurfaceId(), false),
             stub_ignore_c(&memmgr_, GenerateUniqueSurfaceId(), false);
  FakeClient stub1(&memmgr_, GenerateUniqueSurfaceId(), false),
             stub2(&memmgr_, GenerateUniqueSurfaceId(), false);

  FakeClient stub3(&memmgr_, &stub2), stub4(&memmgr_, &stub2);

  // stub1 and stub2 keep their non-hibernated state because they're
  // either visible or the 2 most recently used clients (through the
  // first three checks).
  stub1.SetVisible(true);
  stub2.SetVisible(true);
  Manage();
  EXPECT_TRUE(IsAllocationForegroundForSurfaceYes(stub1.allocation_));
  EXPECT_TRUE(IsAllocationForegroundForSurfaceYes(stub2.allocation_));
  EXPECT_TRUE(IsAllocationForegroundForSurfaceNo(stub3.allocation_));
  EXPECT_TRUE(IsAllocationForegroundForSurfaceNo(stub4.allocation_));

  stub1.SetVisible(false);
  Manage();
  EXPECT_TRUE(IsAllocationBackgroundForSurfaceYes(stub1.allocation_));
  EXPECT_TRUE(IsAllocationForegroundForSurfaceYes(stub2.allocation_));
  EXPECT_TRUE(IsAllocationBackgroundForSurfaceNo(stub3.allocation_));
  EXPECT_TRUE(IsAllocationForegroundForSurfaceNo(stub4.allocation_));

  stub2.SetVisible(false);
  Manage();
  EXPECT_TRUE(IsAllocationBackgroundForSurfaceYes(stub1.allocation_));
  EXPECT_TRUE(IsAllocationBackgroundForSurfaceYes(stub2.allocation_));
  EXPECT_TRUE(IsAllocationBackgroundForSurfaceNo(stub3.allocation_));
  EXPECT_TRUE(IsAllocationBackgroundForSurfaceNo(stub4.allocation_));

  // stub_ignore_b will cause stub1 to become hibernated (because
  // stub_ignore_a, stub_ignore_b, and stub2 are all non-hibernated and more
  // important).
  stub_ignore_b.SetVisible(true);
  stub_ignore_b.SetVisible(false);
  Manage();
  EXPECT_TRUE(IsAllocationHibernatedForSurfaceYes(stub1.allocation_));
  EXPECT_TRUE(IsAllocationBackgroundForSurfaceYes(stub2.allocation_));
  EXPECT_TRUE(IsAllocationBackgroundForSurfaceNo(stub3.allocation_));
  EXPECT_TRUE(IsAllocationBackgroundForSurfaceNo(stub4.allocation_));

  // stub_ignore_c will cause stub2 to become hibernated (because
  // stub_ignore_a, stub_ignore_b, and stub_ignore_c are all non-hibernated
  // and more important).
  stub_ignore_c.SetVisible(true);
  stub_ignore_c.SetVisible(false);
  Manage();
  EXPECT_TRUE(IsAllocationHibernatedForSurfaceYes(stub1.allocation_));
  EXPECT_TRUE(IsAllocationHibernatedForSurfaceYes(stub2.allocation_));
  EXPECT_TRUE(IsAllocationHibernatedForSurfaceNo(stub3.allocation_));
  EXPECT_TRUE(IsAllocationHibernatedForSurfaceNo(stub4.allocation_));
}

}  // namespace content
