Battery Status API: add UMA logging for Linux.
[chromium-blink-merge.git] / content / browser / renderer_host / software_frame_manager_unittest.cc
blobe700f69f15565c2b3f1aa00a68b76836ad9e734d
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.
5 #include "content/browser/renderer_host/software_frame_manager.h"
7 #include <vector>
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"
15 namespace content {
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()));
24 virtual ~FakeSoftwareFrameManagerClient() {
25 HostSharedBitmapManager::current()->ProcessRemoved(
26 base::GetCurrentProcessHandle());
28 virtual void SoftwareFrameWasFreed(uint32 output_surface_id,
29 unsigned frame_id) OVERRIDE {
30 freed_frames_.push_back(std::make_pair(output_surface_id, frame_id));
32 virtual void ReleaseReferencesToSoftwareFrame() OVERRIDE {
33 ++evicted_count_;
36 bool SwapToNewFrame(uint32 output_surface, unsigned frame_id) {
37 cc::SoftwareFrameData frame;
38 frame.id = frame_id;
39 frame.size = gfx::Size(1, 1);
40 frame.damage_rect = gfx::Rect(frame.size);
41 frame.bitmap_id = cc::SharedBitmap::GenerateId();
42 scoped_ptr<base::SharedMemory> memory =
43 make_scoped_ptr(new base::SharedMemory);
44 memory->CreateAnonymous(4);
45 HostSharedBitmapManager::current()->ChildAllocatedSharedBitmap(
46 4, memory->handle(), base::GetCurrentProcessHandle(), frame.bitmap_id);
47 allocated_memory_.push_back(memory.release());
48 return software_frame_manager_->SwapToNewFrame(
49 output_surface, &frame, 1.0, base::GetCurrentProcessHandle());
52 SoftwareFrameManager* software_frame_manager() {
53 return software_frame_manager_.get();
55 size_t freed_frame_count() const { return freed_frames_.size(); }
56 size_t evicted_frame_count() const { return evicted_count_; }
58 private:
59 std::vector<std::pair<uint32,unsigned> > freed_frames_;
60 size_t evicted_count_;
61 ScopedVector<base::SharedMemory> allocated_memory_;
63 scoped_ptr<SoftwareFrameManager> software_frame_manager_;
64 base::WeakPtrFactory<FakeSoftwareFrameManagerClient>
65 weak_ptr_factory_;
67 DISALLOW_COPY_AND_ASSIGN(FakeSoftwareFrameManagerClient);
70 class SoftwareFrameManagerTest : public testing::Test {
71 public:
72 SoftwareFrameManagerTest() {}
73 void AllocateClients(size_t num_clients) {
74 for (size_t i = 0; i < num_clients; ++i)
75 clients_.push_back(new FakeSoftwareFrameManagerClient);
77 void FreeClients() {
78 for (size_t i = 0; i < clients_.size(); ++i)
79 delete clients_[i];
80 clients_.clear();
82 size_t MaxNumberOfSavedFrames() const {
83 size_t result =
84 RendererFrameManager::GetInstance()->max_number_of_saved_frames();
85 return result;
88 protected:
89 std::vector<FakeSoftwareFrameManagerClient*> clients_;
91 private:
92 DISALLOW_COPY_AND_ASSIGN(SoftwareFrameManagerTest);
95 TEST_F(SoftwareFrameManagerTest, DoNotEvictVisible) {
96 // Create twice as many frames as are allowed.
97 AllocateClients(2 * MaxNumberOfSavedFrames());
99 // Swap a visible frame to all clients_. Because they are all visible,
100 // the should not be evicted.
101 for (size_t i = 0; i < clients_.size(); ++i) {
102 bool swap_result = clients_[i]->SwapToNewFrame(
103 static_cast<uint32>(i), 0);
104 clients_[i]->software_frame_manager()->SwapToNewFrameComplete(true);
105 EXPECT_TRUE(swap_result);
106 EXPECT_EQ(0u, clients_[i]->evicted_frame_count());
107 EXPECT_EQ(0u, clients_[i]->freed_frame_count());
109 for (size_t i = 0; i < clients_.size(); ++i) {
110 EXPECT_EQ(0u, clients_[i]->evicted_frame_count());
111 EXPECT_EQ(0u, clients_[i]->freed_frame_count());
114 // Swap another frame and make sure the original was freed (but not evicted).
115 for (size_t i = 0; i < clients_.size(); ++i) {
116 bool swap_result = clients_[i]->SwapToNewFrame(
117 static_cast<uint32>(i), 1);
118 clients_[i]->software_frame_manager()->SwapToNewFrameComplete(true);
119 EXPECT_TRUE(swap_result);
120 EXPECT_EQ(0u, clients_[i]->evicted_frame_count());
121 EXPECT_EQ(1u, clients_[i]->freed_frame_count());
123 for (size_t i = 0; i < clients_.size(); ++i) {
124 EXPECT_EQ(0u, clients_[i]->evicted_frame_count());
125 EXPECT_EQ(1u, clients_[i]->freed_frame_count());
128 // Mark the frames as nonvisible and make sure they start getting evicted.
129 for (size_t i = 0; i < clients_.size(); ++i) {
130 clients_[i]->software_frame_manager()->SetVisibility(false);
131 if (clients_.size() - i > MaxNumberOfSavedFrames()) {
132 EXPECT_EQ(1u, clients_[i]->evicted_frame_count());
133 EXPECT_EQ(2u, clients_[i]->freed_frame_count());
134 } else {
135 EXPECT_EQ(0u, clients_[i]->evicted_frame_count());
136 EXPECT_EQ(1u, clients_[i]->freed_frame_count());
140 // Clean up.
141 FreeClients();
144 TEST_F(SoftwareFrameManagerTest, DoNotEvictDuringSwap) {
145 // Create twice as many frames as are allowed.
146 AllocateClients(2 * MaxNumberOfSavedFrames());
148 // Swap a visible frame to all clients_. Because they are all visible,
149 // the should not be evicted.
150 for (size_t i = 0; i < clients_.size(); ++i) {
151 bool swap_result = clients_[i]->SwapToNewFrame(static_cast<uint32>(i), 0);
152 clients_[i]->software_frame_manager()->SwapToNewFrameComplete(true);
153 EXPECT_TRUE(swap_result);
154 EXPECT_EQ(0u, clients_[i]->evicted_frame_count());
155 EXPECT_EQ(0u, clients_[i]->freed_frame_count());
157 for (size_t i = 0; i < clients_.size(); ++i) {
158 EXPECT_EQ(0u, clients_[i]->evicted_frame_count());
159 EXPECT_EQ(0u, clients_[i]->freed_frame_count());
162 // Now create a test non-visible client, and swap a non-visible frame in.
163 scoped_ptr<FakeSoftwareFrameManagerClient> test_client(
164 new FakeSoftwareFrameManagerClient);
165 test_client->software_frame_manager()->SetVisibility(false);
167 bool swap_result = test_client->SwapToNewFrame(
168 static_cast<uint32>(500), 0);
169 EXPECT_TRUE(swap_result);
170 EXPECT_EQ(0u, test_client->evicted_frame_count());
171 EXPECT_EQ(0u, test_client->freed_frame_count());
172 test_client->software_frame_manager()->SwapToNewFrameComplete(false);
173 EXPECT_EQ(1u, test_client->evicted_frame_count());
174 EXPECT_EQ(1u, test_client->freed_frame_count());
177 // Clean up.
178 FreeClients();
181 TEST_F(SoftwareFrameManagerTest, Cleanup) {
182 // Create twice as many frames as are allowed.
183 AllocateClients(2 * MaxNumberOfSavedFrames());
185 // Swap a visible frame to all clients_. Because they are all visible,
186 // the should not be evicted.
187 for (size_t i = 0; i < clients_.size(); ++i) {
188 bool swap_result = clients_[i]->SwapToNewFrame(static_cast<uint32>(i), 0);
189 clients_[i]->software_frame_manager()->SwapToNewFrameComplete(true);
190 EXPECT_TRUE(swap_result);
191 EXPECT_EQ(0u, clients_[i]->evicted_frame_count());
192 EXPECT_EQ(0u, clients_[i]->freed_frame_count());
195 // Destroy them.
196 FreeClients();
198 // Create the maximum number of frames, all non-visible. They should not
199 // be evicted, because the previous frames were cleaned up at destruction.
200 AllocateClients(MaxNumberOfSavedFrames());
201 for (size_t i = 0; i < clients_.size(); ++i) {
202 cc::SoftwareFrameData frame;
203 bool swap_result = clients_[i]->SwapToNewFrame(static_cast<uint32>(i), 0);
204 clients_[i]->software_frame_manager()->SwapToNewFrameComplete(true);
205 EXPECT_TRUE(swap_result);
206 EXPECT_EQ(0u, clients_[i]->evicted_frame_count());
207 EXPECT_EQ(0u, clients_[i]->freed_frame_count());
209 for (size_t i = 0; i < clients_.size(); ++i) {
210 EXPECT_EQ(0u, clients_[i]->evicted_frame_count());
211 EXPECT_EQ(0u, clients_[i]->freed_frame_count());
214 // Clean up.
215 FreeClients();
218 TEST_F(SoftwareFrameManagerTest, EvictVersusFree) {
219 // Create twice as many frames as are allowed and swap a visible frame to all
220 // clients_. Because they are all visible, the should not be evicted.
221 AllocateClients(2 * MaxNumberOfSavedFrames());
222 for (size_t i = 0; i < clients_.size(); ++i) {
223 clients_[i]->SwapToNewFrame(static_cast<uint32>(i), 0);
224 clients_[i]->software_frame_manager()->SwapToNewFrameComplete(true);
227 // Create a test client with a frame that is not evicted.
228 scoped_ptr<FakeSoftwareFrameManagerClient> test_client(
229 new FakeSoftwareFrameManagerClient);
230 bool swap_result = test_client->SwapToNewFrame(static_cast<uint32>(500), 0);
231 EXPECT_TRUE(swap_result);
232 test_client->software_frame_manager()->SwapToNewFrameComplete(true);
233 EXPECT_EQ(0u, test_client->evicted_frame_count());
234 EXPECT_EQ(0u, test_client->freed_frame_count());
236 // Take out a reference on the current frame and make the memory manager
237 // evict it. The frame will not be freed until this reference is released.
238 cc::TextureMailbox mailbox;
239 scoped_ptr<cc::SingleReleaseCallback> callback;
240 test_client->software_frame_manager()->GetCurrentFrameMailbox(
241 &mailbox, &callback);
242 test_client->software_frame_manager()->SetVisibility(false);
243 EXPECT_EQ(1u, test_client->evicted_frame_count());
244 EXPECT_EQ(0u, test_client->freed_frame_count());
246 // Swap a few frames. The frames will be freed as they are swapped out.
247 for (size_t frame = 0; frame < 10; ++frame) {
248 bool swap_result = test_client->SwapToNewFrame(
249 static_cast<uint32>(500), 1 + static_cast<int>(frame));
250 EXPECT_TRUE(swap_result);
251 test_client->software_frame_manager()->SwapToNewFrameComplete(true);
252 EXPECT_EQ(frame, test_client->freed_frame_count());
253 EXPECT_EQ(1u, test_client->evicted_frame_count());
256 // The reference to the frame that we didn't free is in the callback
257 // object. It will go away when the callback is destroyed.
258 EXPECT_EQ(9u, test_client->freed_frame_count());
259 EXPECT_EQ(1u, test_client->evicted_frame_count());
260 callback->Run(0, false);
261 callback.reset();
262 EXPECT_EQ(10u, test_client->freed_frame_count());
263 EXPECT_EQ(1u, test_client->evicted_frame_count());
265 FreeClients();
268 } // namespace content