OLD | NEW |
1 // Copyright 2015 The Chromium Authors. All rights reserved. | 1 // Copyright 2015 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "cc/resources/resource_pool.h" | 5 #include "cc/resources/resource_pool.h" |
6 | 6 |
| 7 #include <iostream> |
| 8 #include <map> |
| 9 |
7 #include "base/run_loop.h" | 10 #include "base/run_loop.h" |
8 #include "base/thread_task_runner_handle.h" | 11 #include "base/thread_task_runner_handle.h" |
9 #include "cc/resources/resource_util.h" | 12 #include "cc/resources/resource_util.h" |
10 #include "cc/resources/scoped_resource.h" | 13 #include "cc/resources/scoped_resource.h" |
11 #include "cc/test/fake_output_surface.h" | 14 #include "cc/test/fake_output_surface.h" |
12 #include "cc/test/fake_output_surface_client.h" | 15 #include "cc/test/fake_output_surface_client.h" |
13 #include "cc/test/fake_resource_provider.h" | 16 #include "cc/test/fake_resource_provider.h" |
14 #include "cc/test/test_shared_bitmap_manager.h" | 17 #include "cc/test/test_shared_bitmap_manager.h" |
15 #include "testing/gtest/include/gtest/gtest.h" | 18 #include "testing/gtest/include/gtest/gtest.h" |
16 | 19 |
(...skipping 194 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
211 // released within 100 ms, give the thread up to 200. | 214 // released within 100 ms, give the thread up to 200. |
212 base::RunLoop run_loop; | 215 base::RunLoop run_loop; |
213 task_runner_->PostDelayedTask(FROM_HERE, run_loop.QuitClosure(), | 216 task_runner_->PostDelayedTask(FROM_HERE, run_loop.QuitClosure(), |
214 base::TimeDelta::FromMillisecondsD(200)); | 217 base::TimeDelta::FromMillisecondsD(200)); |
215 run_loop.Run(); | 218 run_loop.Run(); |
216 | 219 |
217 EXPECT_EQ(0u, resource_provider_->num_resources()); | 220 EXPECT_EQ(0u, resource_provider_->num_resources()); |
218 EXPECT_EQ(0u, resource_pool_->GetTotalMemoryUsageForTesting()); | 221 EXPECT_EQ(0u, resource_pool_->GetTotalMemoryUsageForTesting()); |
219 } | 222 } |
220 | 223 |
| 224 struct TestResource { |
| 225 explicit TestResource(const gfx::Size& size) { this->size = size; } |
| 226 |
| 227 gfx::Size size; |
| 228 // uint64_t content_id; |
| 229 }; |
| 230 |
| 231 class TestQueueBase { |
| 232 public: |
| 233 virtual TestResource* Create(const gfx::Size& size) = 0; |
| 234 virtual TestResource* Traverse(const gfx::Size& size) = 0; |
| 235 virtual void AppendToUnused(TestResource* resource) = 0; |
| 236 virtual void RemoveAll() = 0; |
| 237 }; |
| 238 |
| 239 class TestDeque : public TestQueueBase { |
| 240 public: |
| 241 TestResource* Create(const gfx::Size& size) override { |
| 242 return new TestResource(size); |
| 243 } |
| 244 |
| 245 // Test traversing logic from ResourcePool::AcquireResource. |
| 246 TestResource* Traverse(const gfx::Size& size) override { |
| 247 for (DQ::iterator it = unused_.begin(); it != unused_.end(); ++it) { |
| 248 TestResource* resource = *it; |
| 249 if (resource->size == size) { |
| 250 unused_.erase(it); |
| 251 return resource; |
| 252 } |
| 253 } |
| 254 |
| 255 return nullptr; |
| 256 } |
| 257 |
| 258 void AppendToUnused(TestResource* resource) override { |
| 259 unused_.push_front(resource); |
| 260 } |
| 261 |
| 262 void RemoveAll() override { |
| 263 for (DQ::iterator it = unused_.begin(); it != unused_.end(); ++it) { |
| 264 delete *it; |
| 265 } |
| 266 unused_.clear(); |
| 267 } |
| 268 |
| 269 private: |
| 270 typedef std::deque<TestResource*> DQ; |
| 271 DQ unused_; |
| 272 }; |
| 273 |
| 274 class TestMultiDeque : public TestQueueBase { |
| 275 public: |
| 276 TestResource* Create(const gfx::Size& size) override { |
| 277 return new TestResource(size); |
| 278 } |
| 279 |
| 280 // Test traversing logic from ResourcePool::AcquireResource. |
| 281 TestResource* Traverse(const gfx::Size& size) override { |
| 282 Key key = std::make_pair(size.width(), size.height()); |
| 283 DQM::iterator kit = unused_.find(key); |
| 284 |
| 285 if (kit != unused_.end()) { |
| 286 DQ* dq = kit->second; |
| 287 |
| 288 for (DQ::iterator it = dq->begin(); it != dq->end(); ++it) { |
| 289 TestResource* resource = *it; |
| 290 if (resource->size == size) { |
| 291 dq->erase(it); |
| 292 return resource; |
| 293 } |
| 294 } |
| 295 } |
| 296 |
| 297 return nullptr; |
| 298 } |
| 299 |
| 300 void AppendToUnused(TestResource* resource) override { |
| 301 Key key = std::make_pair(resource->size.width(), resource->size.height()); |
| 302 DQM::iterator kit = unused_.find(key); |
| 303 if (kit != unused_.end()) { |
| 304 DQ* dq = kit->second; |
| 305 dq->push_front(resource); |
| 306 } else { |
| 307 DQ* dq = new DQ; |
| 308 dq->push_front(resource); |
| 309 unused_[key] = dq; |
| 310 } |
| 311 } |
| 312 |
| 313 void RemoveAll() override { |
| 314 for (DQM::iterator kit = unused_.begin(); kit != unused_.end(); ++kit) { |
| 315 DQ* dq = kit->second; |
| 316 for (DQ::iterator it = dq->begin(); it != dq->end(); ++it) { |
| 317 delete *it; |
| 318 } |
| 319 delete dq; |
| 320 } |
| 321 unused_.clear(); |
| 322 } |
| 323 |
| 324 private: |
| 325 typedef std::pair<int, int> Key; |
| 326 typedef std::deque<TestResource*> DQ; |
| 327 typedef std::map<Key, DQ*> DQM; |
| 328 DQM unused_; |
| 329 }; |
| 330 |
| 331 void DoQueueOperations(TestQueueBase* queue, |
| 332 int how_many, |
| 333 int tile_round_up, |
| 334 int tile_size_max, |
| 335 bool reverse_find) { |
| 336 gfx::Size size; |
| 337 int rounds = tile_size_max / tile_round_up; |
| 338 const int r_max = rounds * rounds * how_many; |
| 339 TestResource* resource[r_max]; |
| 340 // Create and append n resources. |
| 341 int i = 0; |
| 342 for (int w = tile_round_up; w <= tile_size_max; w += tile_round_up) { |
| 343 for (int h = tile_round_up; h <= tile_size_max; h += tile_round_up) { |
| 344 size = gfx::Size(w, h); |
| 345 for (int j = 0; j < how_many; ++j) |
| 346 resource[i++] = queue->Create(size); |
| 347 } |
| 348 } |
| 349 |
| 350 for (i = 0; i < r_max; ++i) |
| 351 queue->AppendToUnused(resource[i]); |
| 352 |
| 353 // Find resource from unused. |
| 354 TestResource* result = nullptr; |
| 355 if (reverse_find) { |
| 356 for (int w = tile_round_up; w <= tile_size_max; w += tile_round_up) { |
| 357 for (int h = tile_round_up; h <= tile_size_max; h += tile_round_up) { |
| 358 size = gfx::Size(w, h); |
| 359 for (int j = 0; j < how_many; ++j) { |
| 360 result = queue->Traverse(size); |
| 361 EXPECT_NE(nullptr, result); |
| 362 delete result; |
| 363 } |
| 364 } |
| 365 } |
| 366 } else { |
| 367 for (int w = tile_size_max; w >= tile_round_up; w -= tile_round_up) { |
| 368 for (int h = tile_size_max; h >= tile_round_up; h -= tile_round_up) { |
| 369 size = gfx::Size(w, h); |
| 370 for (int j = 0; j < how_many; ++j) { |
| 371 result = queue->Traverse(size); |
| 372 EXPECT_NE(nullptr, result); |
| 373 delete result; |
| 374 } |
| 375 } |
| 376 } |
| 377 } |
| 378 } |
| 379 |
| 380 void RunTestQueueCommon(TestQueueBase* queue, |
| 381 std::string test_name, |
| 382 int how_many, |
| 383 int tile_round_up, |
| 384 int tile_size_max) { |
| 385 // Actual Test {{ |
| 386 // Add resource size to be found at the end of queue. |
| 387 base::TimeTicks start = base::TimeTicks::Now(); |
| 388 for (int k = 0; k < 10000; ++k) { |
| 389 DoQueueOperations(queue, how_many, tile_round_up, tile_size_max, false); |
| 390 DoQueueOperations(queue, how_many, tile_round_up, tile_size_max, true); |
| 391 } |
| 392 base::TimeDelta delta = base::TimeTicks::Now() - start; |
| 393 LOG(INFO) << "\n" << test_name << " (" << delta.InMicroseconds() << " µs)"; |
| 394 // Actual Test }} |
| 395 } |
| 396 |
| 397 void RunTestDeque(std::string test_name, |
| 398 int how_many, |
| 399 int tile_round_up, |
| 400 int tile_size_max) { |
| 401 TestDeque queue; |
| 402 RunTestQueueCommon(&queue, test_name, how_many, tile_round_up, tile_size_max); |
| 403 } |
| 404 |
| 405 void RunTestMultiDeque(std::string test_name, |
| 406 int how_many, |
| 407 int tile_round_up, |
| 408 int tile_size_max) { |
| 409 TestMultiDeque queue; |
| 410 RunTestQueueCommon(&queue, test_name, how_many, tile_round_up, tile_size_max); |
| 411 } |
| 412 |
| 413 TEST_F(ResourcePoolTest, TestDequeSingle) { |
| 414 RunTestDeque("TestDequeSingle", 1, 64, 64); |
| 415 } |
| 416 |
| 417 TEST_F(ResourcePoolTest, TestMultiDequeSingle) { |
| 418 RunTestMultiDeque("TestMultiDequeSingle", 1, 64, 64); |
| 419 } |
| 420 |
| 421 TEST_F(ResourcePoolTest, TestDequeManyOfOneSize) { |
| 422 RunTestDeque("TestDequeManyOfOneSize", 50, 64, 64); |
| 423 } |
| 424 |
| 425 TEST_F(ResourcePoolTest, TestMultiDequeManyOfOneSize) { |
| 426 RunTestMultiDeque("TestMultiDequeManyOfOneSize", 50, 64, 64); |
| 427 } |
| 428 |
| 429 TEST_F(ResourcePoolTest, TestDequeOneOfEachSize) { |
| 430 RunTestDeque("TestDequeOneOfEachSize", 1, 64, 512); |
| 431 } |
| 432 |
| 433 TEST_F(ResourcePoolTest, TestMultiDequeOneOfEachSize) { |
| 434 RunTestMultiDeque("TestMultiDequeOneOfEachSize", 1, 64, 512); |
| 435 } |
| 436 |
| 437 TEST_F(ResourcePoolTest, TestDequeManyOfEachSize) { |
| 438 RunTestDeque("TestDequeManyOfEachSize", 5, 64, 512); |
| 439 } |
| 440 |
| 441 TEST_F(ResourcePoolTest, TestMultiDequeManyOfEachSize) { |
| 442 RunTestMultiDeque("TestMultiDequeManyOfEachSize", 5, 64, 512); |
| 443 } |
| 444 |
| 445 TEST_F(ResourcePoolTest, TestDequeTooManyOfEachSize) { |
| 446 RunTestDeque("TestDequeTooManyOfEachSize", 20, 64, 512); |
| 447 } |
| 448 |
| 449 TEST_F(ResourcePoolTest, TestMultiDequeTooManyOfEachSize) { |
| 450 RunTestMultiDeque("TestMultiDequeTooManyOfEachSize", 20, 64, 512); |
| 451 } |
| 452 |
221 } // namespace | 453 } // namespace |
222 } // namespace cc | 454 } // namespace cc |
OLD | NEW |