Update To 11.40.268.0
[platform/framework/web/crosswalk.git] / src / content / browser / renderer_host / software_frame_manager_unittest.cc
1 // Copyright 2013 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/browser/renderer_host/software_frame_manager.h"
6
7 #include <vector>
8
9 #include "base/memory/scoped_vector.h"
10 #include "base/memory/shared_memory.h"
11 #include "base/sys_info.h"
12 #include "content/common/host_shared_bitmap_manager.h"
13 #include "testing/gtest/include/gtest/gtest.h"
14
15 namespace content {
16
17 class FakeSoftwareFrameManagerClient : public SoftwareFrameManagerClient {
18  public:
19   FakeSoftwareFrameManagerClient()
20       : evicted_count_(0), weak_ptr_factory_(this) {
21     software_frame_manager_.reset(new SoftwareFrameManager(
22         weak_ptr_factory_.GetWeakPtr()));
23   }
24   virtual ~FakeSoftwareFrameManagerClient() {
25     HostSharedBitmapManager::current()->ProcessRemoved(
26         base::GetCurrentProcessHandle());
27   }
28   void SoftwareFrameWasFreed(uint32 output_surface_id,
29                              unsigned frame_id) override {
30     freed_frames_.push_back(std::make_pair(output_surface_id, frame_id));
31   }
32   void ReleaseReferencesToSoftwareFrame() override { ++evicted_count_; }
33
34   bool SwapToNewFrame(uint32 output_surface, unsigned frame_id) {
35     cc::SoftwareFrameData frame;
36     frame.id = frame_id;
37     frame.size = gfx::Size(1, 1);
38     frame.damage_rect = gfx::Rect(frame.size);
39     frame.bitmap_id = cc::SharedBitmap::GenerateId();
40     scoped_ptr<base::SharedMemory> memory =
41         make_scoped_ptr(new base::SharedMemory);
42     memory->CreateAnonymous(4);
43     HostSharedBitmapManager::current()->ChildAllocatedSharedBitmap(
44         4, memory->handle(), base::GetCurrentProcessHandle(), frame.bitmap_id);
45     allocated_memory_.push_back(memory.release());
46     return software_frame_manager_->SwapToNewFrame(
47         output_surface, &frame, 1.0, base::GetCurrentProcessHandle());
48   }
49
50   SoftwareFrameManager* software_frame_manager() {
51     return software_frame_manager_.get();
52   }
53   size_t freed_frame_count() const { return freed_frames_.size(); }
54   size_t evicted_frame_count() const { return evicted_count_; }
55
56  private:
57   std::vector<std::pair<uint32,unsigned> > freed_frames_;
58   size_t evicted_count_;
59   ScopedVector<base::SharedMemory> allocated_memory_;
60
61   scoped_ptr<SoftwareFrameManager> software_frame_manager_;
62   base::WeakPtrFactory<FakeSoftwareFrameManagerClient>
63       weak_ptr_factory_;
64
65   DISALLOW_COPY_AND_ASSIGN(FakeSoftwareFrameManagerClient);
66 };
67
68 class SoftwareFrameManagerTest : public testing::Test {
69  public:
70   SoftwareFrameManagerTest() {}
71   void AllocateClients(size_t num_clients) {
72     for (size_t i = 0; i < num_clients; ++i)
73       clients_.push_back(new FakeSoftwareFrameManagerClient);
74   }
75   void FreeClients() {
76     for (size_t i = 0; i < clients_.size(); ++i)
77       delete clients_[i];
78     clients_.clear();
79   }
80   size_t MaxNumberOfSavedFrames() const {
81     size_t result =
82         RendererFrameManager::GetInstance()->max_number_of_saved_frames();
83     return result;
84   }
85
86  protected:
87   std::vector<FakeSoftwareFrameManagerClient*> clients_;
88
89  private:
90   DISALLOW_COPY_AND_ASSIGN(SoftwareFrameManagerTest);
91 };
92
93 TEST_F(SoftwareFrameManagerTest, DoNotEvictVisible) {
94   // Create twice as many frames as are allowed.
95   AllocateClients(2 * MaxNumberOfSavedFrames());
96
97   // Swap a visible frame to all clients_. Because they are all visible,
98   // the should not be evicted.
99   for (size_t i = 0; i < clients_.size(); ++i) {
100     bool swap_result = clients_[i]->SwapToNewFrame(
101         static_cast<uint32>(i), 0);
102     clients_[i]->software_frame_manager()->SwapToNewFrameComplete(true);
103     EXPECT_TRUE(swap_result);
104     EXPECT_EQ(0u, clients_[i]->evicted_frame_count());
105     EXPECT_EQ(0u, clients_[i]->freed_frame_count());
106   }
107   for (size_t i = 0; i < clients_.size(); ++i) {
108     EXPECT_EQ(0u, clients_[i]->evicted_frame_count());
109     EXPECT_EQ(0u, clients_[i]->freed_frame_count());
110   }
111
112   // Swap another frame and make sure the original was freed (but not evicted).
113   for (size_t i = 0; i < clients_.size(); ++i) {
114     bool swap_result = clients_[i]->SwapToNewFrame(
115         static_cast<uint32>(i), 1);
116     clients_[i]->software_frame_manager()->SwapToNewFrameComplete(true);
117     EXPECT_TRUE(swap_result);
118     EXPECT_EQ(0u, clients_[i]->evicted_frame_count());
119     EXPECT_EQ(1u, clients_[i]->freed_frame_count());
120   }
121   for (size_t i = 0; i < clients_.size(); ++i) {
122     EXPECT_EQ(0u, clients_[i]->evicted_frame_count());
123     EXPECT_EQ(1u, clients_[i]->freed_frame_count());
124   }
125
126   // Mark the frames as nonvisible and make sure they start getting evicted.
127   for (size_t i = 0; i < clients_.size(); ++i) {
128     clients_[i]->software_frame_manager()->SetVisibility(false);
129     if (clients_.size() - i > MaxNumberOfSavedFrames()) {
130       EXPECT_EQ(1u, clients_[i]->evicted_frame_count());
131       EXPECT_EQ(2u, clients_[i]->freed_frame_count());
132     } else {
133       EXPECT_EQ(0u, clients_[i]->evicted_frame_count());
134       EXPECT_EQ(1u, clients_[i]->freed_frame_count());
135     }
136   }
137
138   // Clean up.
139   FreeClients();
140 }
141
142 TEST_F(SoftwareFrameManagerTest, DoNotEvictDuringSwap) {
143   // Create twice as many frames as are allowed.
144   AllocateClients(2 * MaxNumberOfSavedFrames());
145
146   // Swap a visible frame to all clients_. Because they are all visible,
147   // the should not be evicted.
148   for (size_t i = 0; i < clients_.size(); ++i) {
149     bool swap_result = clients_[i]->SwapToNewFrame(static_cast<uint32>(i), 0);
150     clients_[i]->software_frame_manager()->SwapToNewFrameComplete(true);
151     EXPECT_TRUE(swap_result);
152     EXPECT_EQ(0u, clients_[i]->evicted_frame_count());
153     EXPECT_EQ(0u, clients_[i]->freed_frame_count());
154   }
155   for (size_t i = 0; i < clients_.size(); ++i) {
156     EXPECT_EQ(0u, clients_[i]->evicted_frame_count());
157     EXPECT_EQ(0u, clients_[i]->freed_frame_count());
158   }
159
160   // Now create a test non-visible client, and swap a non-visible frame in.
161   scoped_ptr<FakeSoftwareFrameManagerClient> test_client(
162       new FakeSoftwareFrameManagerClient);
163   test_client->software_frame_manager()->SetVisibility(false);
164   {
165     bool swap_result = test_client->SwapToNewFrame(
166         static_cast<uint32>(500), 0);
167     EXPECT_TRUE(swap_result);
168     EXPECT_EQ(0u, test_client->evicted_frame_count());
169     EXPECT_EQ(0u, test_client->freed_frame_count());
170     test_client->software_frame_manager()->SwapToNewFrameComplete(false);
171     EXPECT_EQ(1u, test_client->evicted_frame_count());
172     EXPECT_EQ(1u, test_client->freed_frame_count());
173   }
174
175   // Clean up.
176   FreeClients();
177 }
178
179 TEST_F(SoftwareFrameManagerTest, Cleanup) {
180   // Create twice as many frames as are allowed.
181   AllocateClients(2 * MaxNumberOfSavedFrames());
182
183   // Swap a visible frame to all clients_. Because they are all visible,
184   // the should not be evicted.
185   for (size_t i = 0; i < clients_.size(); ++i) {
186     bool swap_result = clients_[i]->SwapToNewFrame(static_cast<uint32>(i), 0);
187     clients_[i]->software_frame_manager()->SwapToNewFrameComplete(true);
188     EXPECT_TRUE(swap_result);
189     EXPECT_EQ(0u, clients_[i]->evicted_frame_count());
190     EXPECT_EQ(0u, clients_[i]->freed_frame_count());
191   }
192
193   // Destroy them.
194   FreeClients();
195
196   // Create the maximum number of frames, all non-visible. They should not
197   // be evicted, because the previous frames were cleaned up at destruction.
198   AllocateClients(MaxNumberOfSavedFrames());
199   for (size_t i = 0; i < clients_.size(); ++i) {
200     cc::SoftwareFrameData frame;
201     bool swap_result = clients_[i]->SwapToNewFrame(static_cast<uint32>(i), 0);
202     clients_[i]->software_frame_manager()->SwapToNewFrameComplete(true);
203     EXPECT_TRUE(swap_result);
204     EXPECT_EQ(0u, clients_[i]->evicted_frame_count());
205     EXPECT_EQ(0u, clients_[i]->freed_frame_count());
206   }
207   for (size_t i = 0; i < clients_.size(); ++i) {
208     EXPECT_EQ(0u, clients_[i]->evicted_frame_count());
209     EXPECT_EQ(0u, clients_[i]->freed_frame_count());
210   }
211
212   // Clean up.
213   FreeClients();
214 }
215
216 TEST_F(SoftwareFrameManagerTest, EvictVersusFree) {
217   // Create twice as many frames as are allowed and swap a visible frame to all
218   // clients_. Because they are all visible, the should not be evicted.
219   AllocateClients(2 * MaxNumberOfSavedFrames());
220   for (size_t i = 0; i < clients_.size(); ++i) {
221     clients_[i]->SwapToNewFrame(static_cast<uint32>(i), 0);
222     clients_[i]->software_frame_manager()->SwapToNewFrameComplete(true);
223   }
224
225   // Create a test client with a frame that is not evicted.
226   scoped_ptr<FakeSoftwareFrameManagerClient> test_client(
227       new FakeSoftwareFrameManagerClient);
228   bool swap_result = test_client->SwapToNewFrame(static_cast<uint32>(500), 0);
229   EXPECT_TRUE(swap_result);
230   test_client->software_frame_manager()->SwapToNewFrameComplete(true);
231   EXPECT_EQ(0u, test_client->evicted_frame_count());
232   EXPECT_EQ(0u, test_client->freed_frame_count());
233
234   // Take out a reference on the current frame and make the memory manager
235   // evict it. The frame will not be freed until this reference is released.
236   cc::TextureMailbox mailbox;
237   scoped_ptr<cc::SingleReleaseCallback> callback;
238   test_client->software_frame_manager()->GetCurrentFrameMailbox(
239       &mailbox, &callback);
240   test_client->software_frame_manager()->SetVisibility(false);
241   EXPECT_EQ(1u, test_client->evicted_frame_count());
242   EXPECT_EQ(0u, test_client->freed_frame_count());
243
244   // Swap a few frames. The frames will be freed as they are swapped out.
245   for (size_t frame = 0; frame < 10; ++frame) {
246     bool swap_result = test_client->SwapToNewFrame(
247         static_cast<uint32>(500), 1 + static_cast<int>(frame));
248     EXPECT_TRUE(swap_result);
249     test_client->software_frame_manager()->SwapToNewFrameComplete(true);
250     EXPECT_EQ(frame, test_client->freed_frame_count());
251     EXPECT_EQ(1u, test_client->evicted_frame_count());
252   }
253
254   // The reference to the frame that we didn't free is in the callback
255   // object. It will go away when the callback is destroyed.
256   EXPECT_EQ(9u, test_client->freed_frame_count());
257   EXPECT_EQ(1u, test_client->evicted_frame_count());
258   callback->Run(0, false);
259   callback.reset();
260   EXPECT_EQ(10u, test_client->freed_frame_count());
261   EXPECT_EQ(1u, test_client->evicted_frame_count());
262
263   FreeClients();
264 }
265
266 }  // namespace content