OLD | NEW |
1 // Copyright 2012 The Chromium Authors. All rights reserved. | 1 // Copyright 2012 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/tile_manager.h" | 5 #include "cc/tile_manager.h" |
6 | 6 |
7 #include <algorithm> | 7 #include <algorithm> |
8 | 8 |
9 #include "base/bind.h" | 9 #include "base/bind.h" |
10 #include "base/command_line.h" | 10 #include "base/command_line.h" |
11 #include "base/debug/trace_event.h" | 11 #include "base/debug/trace_event.h" |
12 #include "base/logging.h" | 12 #include "base/logging.h" |
13 #include "base/string_number_conversions.h" | |
14 #include "base/threading/sequenced_worker_pool.h" | 13 #include "base/threading/sequenced_worker_pool.h" |
15 #include "cc/platform_color.h" | 14 #include "cc/platform_color.h" |
16 #include "cc/rendering_stats.h" | 15 #include "cc/rendering_stats.h" |
17 #include "cc/resource_pool.h" | 16 #include "cc/resource_pool.h" |
18 #include "cc/switches.h" | 17 #include "cc/switches.h" |
19 #include "cc/tile.h" | 18 #include "cc/tile.h" |
20 #include "third_party/skia/include/core/SkDevice.h" | 19 #include "third_party/skia/include/core/SkDevice.h" |
21 | 20 |
22 namespace { | 21 namespace { |
23 | 22 |
24 void RasterizeTile(cc::PicturePileImpl* picture_pile, | 23 void RasterizeTile(cc::PicturePileImpl* picture_pile, |
25 uint8_t* mapped_buffer, | 24 uint8_t* mapped_buffer, |
26 const gfx::Rect& rect, | 25 const gfx::Rect& rect, |
27 cc::RenderingStats* stats) { | 26 cc::RenderingStats* stats) { |
28 TRACE_EVENT0("cc", "RasterizeTile"); | 27 TRACE_EVENT0("cc", "RasterizeTile"); |
29 DCHECK(mapped_buffer); | 28 DCHECK(mapped_buffer); |
30 DCHECK(picture_pile); | 29 DCHECK(picture_pile); |
31 SkBitmap bitmap; | 30 SkBitmap bitmap; |
32 bitmap.setConfig(SkBitmap::kARGB_8888_Config, rect.width(), rect.height()); | 31 bitmap.setConfig(SkBitmap::kARGB_8888_Config, rect.width(), rect.height()); |
33 bitmap.setPixels(mapped_buffer); | 32 bitmap.setPixels(mapped_buffer); |
34 SkDevice device(bitmap); | 33 SkDevice device(bitmap); |
35 SkCanvas canvas(&device); | 34 SkCanvas canvas(&device); |
36 picture_pile->Raster(&canvas, rect, stats); | 35 picture_pile->Raster(&canvas, rect, stats); |
37 } | 36 } |
38 | 37 |
39 const int kMaxRasterThreads = 64; | |
40 const int kDefaultNumberOfRasterThreads = 1; | |
41 | |
42 const char* kRasterThreadNamePrefix = "CompositorRaster"; | 38 const char* kRasterThreadNamePrefix = "CompositorRaster"; |
43 | 39 |
44 // Allow two pending raster tasks per thread. This keeps resource usage | 40 // Allow two pending raster tasks per thread. This keeps resource usage |
45 // low while making sure raster threads aren't unnecessarily idle. | 41 // low while making sure raster threads aren't unnecessarily idle. |
46 const int kNumPendingRasterTasksPerThread = 2; | 42 const int kNumPendingRasterTasksPerThread = 2; |
47 | 43 |
48 } // namespace | 44 } // namespace |
49 | 45 |
50 namespace cc { | 46 namespace cc { |
51 | 47 |
52 ManagedTileState::ManagedTileState() | 48 ManagedTileState::ManagedTileState() |
53 : can_use_gpu_memory(false), | 49 : can_use_gpu_memory(false), |
54 can_be_freed(true), | 50 can_be_freed(true), |
55 resource_id(0), | 51 resource_id(0), |
56 resource_id_is_being_initialized(false), | 52 resource_id_is_being_initialized(false), |
57 contents_swizzled(false) { | 53 contents_swizzled(false) { |
58 } | 54 } |
59 | 55 |
60 ManagedTileState::~ManagedTileState() { | 56 ManagedTileState::~ManagedTileState() { |
61 DCHECK(!resource_id); | 57 DCHECK(!resource_id); |
62 DCHECK(!resource_id_is_being_initialized); | 58 DCHECK(!resource_id_is_being_initialized); |
63 } | 59 } |
64 | 60 |
65 TileManager::TileManager( | 61 TileManager::TileManager( |
66 TileManagerClient* client, ResourceProvider* resource_provider) | 62 TileManagerClient* client, |
| 63 ResourceProvider* resource_provider, |
| 64 size_t num_raster_threads) |
67 : client_(client), | 65 : client_(client), |
68 resource_pool_(ResourcePool::Create(resource_provider, | 66 resource_pool_(ResourcePool::Create(resource_provider, |
69 Renderer::ImplPool)), | 67 Renderer::ImplPool)), |
70 manage_tiles_pending_(false), | 68 manage_tiles_pending_(false), |
71 pending_raster_tasks_(0) { | 69 pending_raster_tasks_(0), |
72 size_t worker_threads = kDefaultNumberOfRasterThreads; | 70 num_raster_threads_(num_raster_threads), |
73 if (CommandLine::ForCurrentProcess()->HasSwitch( | 71 worker_pool_(new base::SequencedWorkerPool(num_raster_threads, |
74 cc::switches::kNumRasterThreads)) { | 72 kRasterThreadNamePrefix)) { |
75 std::string num_raster_threads = | |
76 CommandLine::ForCurrentProcess()->GetSwitchValueASCII( | |
77 cc::switches::kNumRasterThreads); | |
78 int num_threads; | |
79 if (base::StringToInt(num_raster_threads, &num_threads) && | |
80 num_threads > 0 && num_threads <= kMaxRasterThreads) { | |
81 worker_threads = num_threads; | |
82 } else { | |
83 LOG(WARNING) << "Bad number of raster threads: " << num_raster_threads; | |
84 } | |
85 } | |
86 worker_pool_ = new base::SequencedWorkerPool(worker_threads, | |
87 kRasterThreadNamePrefix); | |
88 } | 73 } |
89 | 74 |
90 TileManager::~TileManager() { | 75 TileManager::~TileManager() { |
91 // Reset global state and manage. This should cause | 76 // Reset global state and manage. This should cause |
92 // our memory usage to drop to zero. | 77 // our memory usage to drop to zero. |
93 global_state_ = GlobalStateThatImpactsTilePriority(); | 78 global_state_ = GlobalStateThatImpactsTilePriority(); |
94 ManageTiles(); | 79 ManageTiles(); |
95 DCHECK(tiles_.size() == 0); | 80 DCHECK(tiles_.size() == 0); |
96 // This should finish all pending raster tasks and release any | 81 // This should finish all pending raster tasks and release any |
97 // uninitialized resources. | 82 // uninitialized resources. |
(...skipping 197 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
295 DCHECK(managed_tile_state.can_be_freed); | 280 DCHECK(managed_tile_state.can_be_freed); |
296 if (managed_tile_state.resource_id) { | 281 if (managed_tile_state.resource_id) { |
297 resource_pool_->ReleaseResource(managed_tile_state.resource_id); | 282 resource_pool_->ReleaseResource(managed_tile_state.resource_id); |
298 managed_tile_state.resource_id = 0; | 283 managed_tile_state.resource_id = 0; |
299 } | 284 } |
300 } | 285 } |
301 | 286 |
302 void TileManager::DispatchMoreRasterTasks() { | 287 void TileManager::DispatchMoreRasterTasks() { |
303 while (!tiles_that_need_to_be_rasterized_.empty()) { | 288 while (!tiles_that_need_to_be_rasterized_.empty()) { |
304 int max_pending_tasks = kNumPendingRasterTasksPerThread * | 289 int max_pending_tasks = kNumPendingRasterTasksPerThread * |
305 kMaxRasterThreads; | 290 num_raster_threads_; |
306 | 291 |
307 // Stop dispatching raster tasks when too many are pending. | 292 // Stop dispatching raster tasks when too many are pending. |
308 if (pending_raster_tasks_ >= max_pending_tasks) | 293 if (pending_raster_tasks_ >= max_pending_tasks) |
309 break; | 294 break; |
310 | 295 |
311 DispatchOneRasterTask(tiles_that_need_to_be_rasterized_.back()); | 296 DispatchOneRasterTask(tiles_that_need_to_be_rasterized_.back()); |
312 tiles_that_need_to_be_rasterized_.pop_back(); | 297 tiles_that_need_to_be_rasterized_.pop_back(); |
313 } | 298 } |
314 } | 299 } |
315 | 300 |
(...skipping 83 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
399 Tile* tile, ResourceProvider::ResourceId resource_id) { | 384 Tile* tile, ResourceProvider::ResourceId resource_id) { |
400 ManagedTileState& managed_tile_state = tile->managed_state(); | 385 ManagedTileState& managed_tile_state = tile->managed_state(); |
401 DCHECK(!managed_tile_state.resource_id); | 386 DCHECK(!managed_tile_state.resource_id); |
402 managed_tile_state.resource_id = resource_id; | 387 managed_tile_state.resource_id = resource_id; |
403 managed_tile_state.resource_id_is_being_initialized = false; | 388 managed_tile_state.resource_id_is_being_initialized = false; |
404 // TODO(qinmin): Make this conditional on managed_tile_state.bin == NOW_BIN. | 389 // TODO(qinmin): Make this conditional on managed_tile_state.bin == NOW_BIN. |
405 client_->ScheduleRedraw(); | 390 client_->ScheduleRedraw(); |
406 } | 391 } |
407 | 392 |
408 } | 393 } |
OLD | NEW |