11e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)// Copyright 2013 The Chromium Authors. All rights reserved.
21e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
31e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)// found in the LICENSE file.
41e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)
51e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)#include "content/browser/renderer_host/software_frame_manager.h"
61e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)
71e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)#include <vector>
81e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)
9c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch#include "base/memory/scoped_vector.h"
10c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch#include "base/memory/shared_memory.h"
111e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)#include "base/sys_info.h"
12c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch#include "content/common/host_shared_bitmap_manager.h"
131e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)#include "testing/gtest/include/gtest/gtest.h"
141e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)
151e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)namespace content {
161e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)
171e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)class FakeSoftwareFrameManagerClient : public SoftwareFrameManagerClient {
181e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) public:
191e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  FakeSoftwareFrameManagerClient()
201e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)      : evicted_count_(0), weak_ptr_factory_(this) {
211e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    software_frame_manager_.reset(new SoftwareFrameManager(
221e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)        weak_ptr_factory_.GetWeakPtr()));
231e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  }
24c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  virtual ~FakeSoftwareFrameManagerClient() {
25c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch    HostSharedBitmapManager::current()->ProcessRemoved(
26c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch        base::GetCurrentProcessHandle());
27c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  }
28c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  virtual void SoftwareFrameWasFreed(uint32 output_surface_id,
29c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch                                     unsigned frame_id) OVERRIDE {
301e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    freed_frames_.push_back(std::make_pair(output_surface_id, frame_id));
311e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  }
321e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  virtual void ReleaseReferencesToSoftwareFrame() OVERRIDE {
331e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    ++evicted_count_;
341e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  }
351e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)
361e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  bool SwapToNewFrame(uint32 output_surface, unsigned frame_id) {
371e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    cc::SoftwareFrameData frame;
381e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    frame.id = frame_id;
391e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    frame.size = gfx::Size(1, 1);
401e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    frame.damage_rect = gfx::Rect(frame.size);
41c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch    frame.bitmap_id = cc::SharedBitmap::GenerateId();
42c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch    scoped_ptr<base::SharedMemory> memory =
43c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch        make_scoped_ptr(new base::SharedMemory);
44c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch    memory->CreateAnonymous(4);
45c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch    HostSharedBitmapManager::current()->ChildAllocatedSharedBitmap(
46c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch        4, memory->handle(), base::GetCurrentProcessHandle(), frame.bitmap_id);
47c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch    allocated_memory_.push_back(memory.release());
481e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    return software_frame_manager_->SwapToNewFrame(
491e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)        output_surface, &frame, 1.0, base::GetCurrentProcessHandle());
501e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  }
511e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)
521e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  SoftwareFrameManager* software_frame_manager() {
531e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    return software_frame_manager_.get();
541e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  }
551e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  size_t freed_frame_count() const { return freed_frames_.size(); }
561e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  size_t evicted_frame_count() const { return evicted_count_; }
571e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)
581e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) private:
591e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  std::vector<std::pair<uint32,unsigned> > freed_frames_;
601e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  size_t evicted_count_;
61c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  ScopedVector<base::SharedMemory> allocated_memory_;
621e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)
631e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  scoped_ptr<SoftwareFrameManager> software_frame_manager_;
641e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  base::WeakPtrFactory<FakeSoftwareFrameManagerClient>
651e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)      weak_ptr_factory_;
661e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)
671e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  DISALLOW_COPY_AND_ASSIGN(FakeSoftwareFrameManagerClient);
681e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)};
691e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)
701e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)class SoftwareFrameManagerTest : public testing::Test {
711e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) public:
721e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  SoftwareFrameManagerTest() {}
731e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  void AllocateClients(size_t num_clients) {
741e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    for (size_t i = 0; i < num_clients; ++i)
751e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)      clients_.push_back(new FakeSoftwareFrameManagerClient);
761e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  }
771e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  void FreeClients() {
781e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    for (size_t i = 0; i < clients_.size(); ++i)
791e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)      delete clients_[i];
801e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    clients_.clear();
811e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  }
821e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  size_t MaxNumberOfSavedFrames() const {
831e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    size_t result =
841e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)        RendererFrameManager::GetInstance()->max_number_of_saved_frames();
851e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    return result;
861e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  }
871e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)
881e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) protected:
891e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  std::vector<FakeSoftwareFrameManagerClient*> clients_;
901e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)
911e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) private:
921e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  DISALLOW_COPY_AND_ASSIGN(SoftwareFrameManagerTest);
931e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)};
941e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)
951e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)TEST_F(SoftwareFrameManagerTest, DoNotEvictVisible) {
961e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  // Create twice as many frames as are allowed.
971e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  AllocateClients(2 * MaxNumberOfSavedFrames());
981e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)
991e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  // Swap a visible frame to all clients_. Because they are all visible,
1001e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  // the should not be evicted.
1011e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  for (size_t i = 0; i < clients_.size(); ++i) {
1021e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    bool swap_result = clients_[i]->SwapToNewFrame(
1031e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)        static_cast<uint32>(i), 0);
1041e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    clients_[i]->software_frame_manager()->SwapToNewFrameComplete(true);
1051e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    EXPECT_TRUE(swap_result);
1061e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    EXPECT_EQ(0u, clients_[i]->evicted_frame_count());
1071e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    EXPECT_EQ(0u, clients_[i]->freed_frame_count());
1081e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  }
1091e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  for (size_t i = 0; i < clients_.size(); ++i) {
1101e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    EXPECT_EQ(0u, clients_[i]->evicted_frame_count());
1111e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    EXPECT_EQ(0u, clients_[i]->freed_frame_count());
1121e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  }
1131e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)
1141e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  // Swap another frame and make sure the original was freed (but not evicted).
1151e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  for (size_t i = 0; i < clients_.size(); ++i) {
1161e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    bool swap_result = clients_[i]->SwapToNewFrame(
1171e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)        static_cast<uint32>(i), 1);
1181e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    clients_[i]->software_frame_manager()->SwapToNewFrameComplete(true);
1191e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    EXPECT_TRUE(swap_result);
1201e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    EXPECT_EQ(0u, clients_[i]->evicted_frame_count());
1211e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    EXPECT_EQ(1u, clients_[i]->freed_frame_count());
1221e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  }
1231e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  for (size_t i = 0; i < clients_.size(); ++i) {
1241e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    EXPECT_EQ(0u, clients_[i]->evicted_frame_count());
1251e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    EXPECT_EQ(1u, clients_[i]->freed_frame_count());
1261e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  }
1271e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)
1281e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  // Mark the frames as nonvisible and make sure they start getting evicted.
1291e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  for (size_t i = 0; i < clients_.size(); ++i) {
1301e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    clients_[i]->software_frame_manager()->SetVisibility(false);
1311e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    if (clients_.size() - i > MaxNumberOfSavedFrames()) {
1321e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)      EXPECT_EQ(1u, clients_[i]->evicted_frame_count());
1331e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)      EXPECT_EQ(2u, clients_[i]->freed_frame_count());
1341e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    } else {
1351e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)      EXPECT_EQ(0u, clients_[i]->evicted_frame_count());
1361e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)      EXPECT_EQ(1u, clients_[i]->freed_frame_count());
1371e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    }
1381e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  }
1391e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)
1401e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  // Clean up.
1411e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  FreeClients();
1421e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)}
1431e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)
1441e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)TEST_F(SoftwareFrameManagerTest, DoNotEvictDuringSwap) {
1451e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  // Create twice as many frames as are allowed.
1461e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  AllocateClients(2 * MaxNumberOfSavedFrames());
1471e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)
1481e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  // Swap a visible frame to all clients_. Because they are all visible,
1491e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  // the should not be evicted.
1501e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  for (size_t i = 0; i < clients_.size(); ++i) {
1511e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    bool swap_result = clients_[i]->SwapToNewFrame(static_cast<uint32>(i), 0);
1521e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    clients_[i]->software_frame_manager()->SwapToNewFrameComplete(true);
1531e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    EXPECT_TRUE(swap_result);
1541e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    EXPECT_EQ(0u, clients_[i]->evicted_frame_count());
1551e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    EXPECT_EQ(0u, clients_[i]->freed_frame_count());
1561e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  }
1571e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  for (size_t i = 0; i < clients_.size(); ++i) {
1581e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    EXPECT_EQ(0u, clients_[i]->evicted_frame_count());
1591e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    EXPECT_EQ(0u, clients_[i]->freed_frame_count());
1601e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  }
1611e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)
1621e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  // Now create a test non-visible client, and swap a non-visible frame in.
1631e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  scoped_ptr<FakeSoftwareFrameManagerClient> test_client(
1641e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)      new FakeSoftwareFrameManagerClient);
1651e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  test_client->software_frame_manager()->SetVisibility(false);
1661e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  {
1671e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    bool swap_result = test_client->SwapToNewFrame(
1681e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)        static_cast<uint32>(500), 0);
1691e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    EXPECT_TRUE(swap_result);
1701e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    EXPECT_EQ(0u, test_client->evicted_frame_count());
1711e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    EXPECT_EQ(0u, test_client->freed_frame_count());
1721e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    test_client->software_frame_manager()->SwapToNewFrameComplete(false);
1731e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    EXPECT_EQ(1u, test_client->evicted_frame_count());
1741e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    EXPECT_EQ(1u, test_client->freed_frame_count());
1751e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  }
1761e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)
1771e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  // Clean up.
1781e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  FreeClients();
1791e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)}
1801e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)
1811e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)TEST_F(SoftwareFrameManagerTest, Cleanup) {
1821e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  // Create twice as many frames as are allowed.
1831e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  AllocateClients(2 * MaxNumberOfSavedFrames());
1841e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)
1851e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  // Swap a visible frame to all clients_. Because they are all visible,
1861e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  // the should not be evicted.
1871e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  for (size_t i = 0; i < clients_.size(); ++i) {
1881e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    bool swap_result = clients_[i]->SwapToNewFrame(static_cast<uint32>(i), 0);
1891e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    clients_[i]->software_frame_manager()->SwapToNewFrameComplete(true);
1901e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    EXPECT_TRUE(swap_result);
1911e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    EXPECT_EQ(0u, clients_[i]->evicted_frame_count());
1921e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    EXPECT_EQ(0u, clients_[i]->freed_frame_count());
1931e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  }
1941e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)
1951e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  // Destroy them.
1961e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  FreeClients();
1971e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)
1981e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  // Create the maximum number of frames, all non-visible. They should not
1991e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  // be evicted, because the previous frames were cleaned up at destruction.
2001e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  AllocateClients(MaxNumberOfSavedFrames());
2011e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  for (size_t i = 0; i < clients_.size(); ++i) {
2021e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    cc::SoftwareFrameData frame;
2031e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    bool swap_result = clients_[i]->SwapToNewFrame(static_cast<uint32>(i), 0);
2041e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    clients_[i]->software_frame_manager()->SwapToNewFrameComplete(true);
2051e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    EXPECT_TRUE(swap_result);
2061e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    EXPECT_EQ(0u, clients_[i]->evicted_frame_count());
2071e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    EXPECT_EQ(0u, clients_[i]->freed_frame_count());
2081e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  }
2091e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  for (size_t i = 0; i < clients_.size(); ++i) {
2101e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    EXPECT_EQ(0u, clients_[i]->evicted_frame_count());
2111e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    EXPECT_EQ(0u, clients_[i]->freed_frame_count());
2121e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  }
2131e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)
2141e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  // Clean up.
2151e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  FreeClients();
2161e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)}
2171e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)
2181e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)TEST_F(SoftwareFrameManagerTest, EvictVersusFree) {
2191e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  // Create twice as many frames as are allowed and swap a visible frame to all
2201e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  // clients_. Because they are all visible, the should not be evicted.
2211e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  AllocateClients(2 * MaxNumberOfSavedFrames());
2221e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  for (size_t i = 0; i < clients_.size(); ++i) {
2231e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    clients_[i]->SwapToNewFrame(static_cast<uint32>(i), 0);
2241e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    clients_[i]->software_frame_manager()->SwapToNewFrameComplete(true);
2251e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  }
2261e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)
2271e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  // Create a test client with a frame that is not evicted.
2281e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  scoped_ptr<FakeSoftwareFrameManagerClient> test_client(
2291e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)      new FakeSoftwareFrameManagerClient);
2301e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  bool swap_result = test_client->SwapToNewFrame(static_cast<uint32>(500), 0);
2311e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  EXPECT_TRUE(swap_result);
2321e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  test_client->software_frame_manager()->SwapToNewFrameComplete(true);
2331e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  EXPECT_EQ(0u, test_client->evicted_frame_count());
2341e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  EXPECT_EQ(0u, test_client->freed_frame_count());
2351e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)
2361e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  // Take out a reference on the current frame and make the memory manager
2371e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  // evict it. The frame will not be freed until this reference is released.
2381e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  cc::TextureMailbox mailbox;
2391e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  scoped_ptr<cc::SingleReleaseCallback> callback;
2401e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  test_client->software_frame_manager()->GetCurrentFrameMailbox(
2411e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)      &mailbox, &callback);
2421e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  test_client->software_frame_manager()->SetVisibility(false);
2431e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  EXPECT_EQ(1u, test_client->evicted_frame_count());
2441e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  EXPECT_EQ(0u, test_client->freed_frame_count());
2451e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)
2461e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  // Swap a few frames. The frames will be freed as they are swapped out.
2471e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  for (size_t frame = 0; frame < 10; ++frame) {
2481e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    bool swap_result = test_client->SwapToNewFrame(
2491e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)        static_cast<uint32>(500), 1 + static_cast<int>(frame));
2501e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    EXPECT_TRUE(swap_result);
2511e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    test_client->software_frame_manager()->SwapToNewFrameComplete(true);
2521e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    EXPECT_EQ(frame, test_client->freed_frame_count());
2531e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    EXPECT_EQ(1u, test_client->evicted_frame_count());
2541e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  }
2551e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)
2561e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  // The reference to the frame that we didn't free is in the callback
2571e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  // object. It will go away when the callback is destroyed.
2581e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  EXPECT_EQ(9u, test_client->freed_frame_count());
2591e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  EXPECT_EQ(1u, test_client->evicted_frame_count());
2601e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  callback->Run(0, false);
2611e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  callback.reset();
2621e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  EXPECT_EQ(10u, test_client->freed_frame_count());
2631e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  EXPECT_EQ(1u, test_client->evicted_frame_count());
2641e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)
2651e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  FreeClients();
2661e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)}
2671e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)
2681e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)}  // namespace content
269