Torne (Richard Coles) | 2a99a7e | 2013-03-28 15:31:22 +0000 | [diff] [blame] | 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 |
| 3 | // found in the LICENSE file. |
| 4 | |
| 5 | #include "cc/resources/tile_manager.h" |
| 6 | |
| 7 | #include <algorithm> |
Ben Murdoch | eb525c5 | 2013-07-10 11:40:50 +0100 | [diff] [blame] | 8 | #include <limits> |
Torne (Richard Coles) | c2e0dbd | 2013-05-09 18:35:53 +0100 | [diff] [blame] | 9 | #include <string> |
Torne (Richard Coles) | 2a99a7e | 2013-03-28 15:31:22 +0000 | [diff] [blame] | 10 | |
| 11 | #include "base/bind.h" |
Torne (Richard Coles) | 2a99a7e | 2013-03-28 15:31:22 +0000 | [diff] [blame] | 12 | #include "base/json/json_writer.h" |
| 13 | #include "base/logging.h" |
| 14 | #include "base/metrics/histogram.h" |
| 15 | #include "cc/debug/devtools_instrumentation.h" |
Torne (Richard Coles) | b2df76e | 2013-05-13 16:52:09 +0100 | [diff] [blame] | 16 | #include "cc/debug/traced_value.h" |
Torne (Richard Coles) | 868fa2f | 2013-06-11 10:57:03 +0100 | [diff] [blame] | 17 | #include "cc/resources/image_raster_worker_pool.h" |
| 18 | #include "cc/resources/pixel_buffer_raster_worker_pool.h" |
Torne (Richard Coles) | 2a99a7e | 2013-03-28 15:31:22 +0000 | [diff] [blame] | 19 | #include "cc/resources/tile.h" |
Torne (Richard Coles) | 868fa2f | 2013-06-11 10:57:03 +0100 | [diff] [blame] | 20 | #include "third_party/skia/include/core/SkCanvas.h" |
Torne (Richard Coles) | a93a17c | 2013-05-15 11:34:50 +0100 | [diff] [blame] | 21 | #include "ui/gfx/rect_conversions.h" |
Torne (Richard Coles) | 2a99a7e | 2013-03-28 15:31:22 +0000 | [diff] [blame] | 22 | |
| 23 | namespace cc { |
| 24 | |
| 25 | namespace { |
| 26 | |
Torne (Richard Coles) | a36e592 | 2013-08-05 13:57:33 +0100 | [diff] [blame] | 27 | // Memory limit policy works by mapping some bin states to the NEVER bin. |
| 28 | const ManagedTileBin kBinPolicyMap[NUM_TILE_MEMORY_LIMIT_POLICIES][NUM_BINS] = { |
| 29 | { // [ALLOW_NOTHING] |
Ben Murdoch | bb1529c | 2013-08-08 10:24:53 +0100 | [diff] [blame^] | 30 | NEVER_BIN, // [NOW_AND_READY_TO_DRAW_BIN] |
| 31 | NEVER_BIN, // [NOW_BIN] |
| 32 | NEVER_BIN, // [SOON_BIN] |
| 33 | NEVER_BIN, // [EVENTUALLY_AND_ACTIVE_BIN] |
| 34 | NEVER_BIN, // [EVENTUALLY_BIN] |
| 35 | NEVER_BIN, // [NEVER_AND_ACTIVE_BIN] |
| 36 | NEVER_BIN // [NEVER_BIN] |
Torne (Richard Coles) | a36e592 | 2013-08-05 13:57:33 +0100 | [diff] [blame] | 37 | }, { // [ALLOW_ABSOLUTE_MINIMUM] |
Ben Murdoch | bb1529c | 2013-08-08 10:24:53 +0100 | [diff] [blame^] | 38 | NOW_AND_READY_TO_DRAW_BIN, // [NOW_AND_READY_TO_DRAW_BIN] |
| 39 | NOW_BIN, // [NOW_BIN] |
| 40 | NEVER_BIN, // [SOON_BIN] |
| 41 | NEVER_BIN, // [EVENTUALLY_AND_ACTIVE_BIN] |
| 42 | NEVER_BIN, // [EVENTUALLY_BIN] |
| 43 | NEVER_BIN, // [NEVER_AND_ACTIVE_BIN] |
| 44 | NEVER_BIN // [NEVER_BIN] |
Torne (Richard Coles) | a36e592 | 2013-08-05 13:57:33 +0100 | [diff] [blame] | 45 | }, { // [ALLOW_PREPAINT_ONLY] |
Ben Murdoch | bb1529c | 2013-08-08 10:24:53 +0100 | [diff] [blame^] | 46 | NOW_AND_READY_TO_DRAW_BIN, // [NOW_AND_READY_TO_DRAW_BIN] |
| 47 | NOW_BIN, // [NOW_BIN] |
| 48 | SOON_BIN, // [SOON_BIN] |
| 49 | NEVER_BIN, // [EVENTUALLY_AND_ACTIVE_BIN] |
| 50 | NEVER_BIN, // [EVENTUALLY_BIN] |
| 51 | NEVER_BIN, // [NEVER_AND_ACTIVE_BIN] |
| 52 | NEVER_BIN // [NEVER_BIN] |
Torne (Richard Coles) | a36e592 | 2013-08-05 13:57:33 +0100 | [diff] [blame] | 53 | }, { // [ALLOW_ANYTHING] |
Ben Murdoch | bb1529c | 2013-08-08 10:24:53 +0100 | [diff] [blame^] | 54 | NOW_AND_READY_TO_DRAW_BIN, // [NOW_AND_READY_TO_DRAW_BIN] |
| 55 | NOW_BIN, // [NOW_BIN] |
| 56 | SOON_BIN, // [SOON_BIN] |
| 57 | EVENTUALLY_AND_ACTIVE_BIN, // [EVENTUALLY_AND_ACTIVE_BIN] |
| 58 | EVENTUALLY_BIN, // [EVENTUALLY_BIN] |
| 59 | NEVER_AND_ACTIVE_BIN, // [NEVER_AND_ACTIVE_BIN] |
| 60 | NEVER_BIN // [NEVER_BIN] |
Torne (Richard Coles) | a36e592 | 2013-08-05 13:57:33 +0100 | [diff] [blame] | 61 | } |
| 62 | }; |
| 63 | |
Torne (Richard Coles) | 2a99a7e | 2013-03-28 15:31:22 +0000 | [diff] [blame] | 64 | // Determine bin based on three categories of tiles: things we need now, |
| 65 | // things we need soon, and eventually. |
Ben Murdoch | 7dbb3d5 | 2013-07-17 14:55:54 +0100 | [diff] [blame] | 66 | inline ManagedTileBin BinFromTilePriority(const TilePriority& prio, |
Ben Murdoch | bb1529c | 2013-08-08 10:24:53 +0100 | [diff] [blame^] | 67 | TreePriority tree_priority, |
| 68 | bool is_ready_to_draw, |
| 69 | bool is_active) { |
Torne (Richard Coles) | 2a99a7e | 2013-03-28 15:31:22 +0000 | [diff] [blame] | 70 | // The amount of time for which we want to have prepainting coverage. |
| 71 | const float kPrepaintingWindowTimeSeconds = 1.0f; |
| 72 | const float kBackflingGuardDistancePixels = 314.0f; |
| 73 | |
Torne (Richard Coles) | 7d4cd47 | 2013-06-19 11:58:07 +0100 | [diff] [blame] | 74 | // Don't let low res tiles be in the now bin unless we're in a mode where |
| 75 | // we're prioritizing checkerboard prevention. |
| 76 | bool can_be_in_now_bin = tree_priority == SMOOTHNESS_TAKES_PRIORITY || |
| 77 | prio.resolution != LOW_RESOLUTION; |
| 78 | |
Ben Murdoch | eb525c5 | 2013-07-10 11:40:50 +0100 | [diff] [blame] | 79 | if (prio.distance_to_visible_in_pixels == |
| 80 | std::numeric_limits<float>::infinity()) |
Ben Murdoch | bb1529c | 2013-08-08 10:24:53 +0100 | [diff] [blame^] | 81 | return is_active ? NEVER_AND_ACTIVE_BIN : NEVER_BIN; |
Ben Murdoch | eb525c5 | 2013-07-10 11:40:50 +0100 | [diff] [blame] | 82 | |
Torne (Richard Coles) | 7d4cd47 | 2013-06-19 11:58:07 +0100 | [diff] [blame] | 83 | if (can_be_in_now_bin && prio.time_to_visible_in_seconds == 0) |
Ben Murdoch | bb1529c | 2013-08-08 10:24:53 +0100 | [diff] [blame^] | 84 | return is_ready_to_draw ? NOW_AND_READY_TO_DRAW_BIN : NOW_BIN; |
Torne (Richard Coles) | 2a99a7e | 2013-03-28 15:31:22 +0000 | [diff] [blame] | 85 | |
| 86 | if (prio.resolution == NON_IDEAL_RESOLUTION) |
Ben Murdoch | bb1529c | 2013-08-08 10:24:53 +0100 | [diff] [blame^] | 87 | return is_active ? EVENTUALLY_AND_ACTIVE_BIN : EVENTUALLY_BIN; |
Torne (Richard Coles) | 2a99a7e | 2013-03-28 15:31:22 +0000 | [diff] [blame] | 88 | |
Torne (Richard Coles) | b2df76e | 2013-05-13 16:52:09 +0100 | [diff] [blame] | 89 | if (prio.distance_to_visible_in_pixels < kBackflingGuardDistancePixels || |
| 90 | prio.time_to_visible_in_seconds < kPrepaintingWindowTimeSeconds) |
Torne (Richard Coles) | 2a99a7e | 2013-03-28 15:31:22 +0000 | [diff] [blame] | 91 | return SOON_BIN; |
| 92 | |
Ben Murdoch | bb1529c | 2013-08-08 10:24:53 +0100 | [diff] [blame^] | 93 | return is_active ? EVENTUALLY_AND_ACTIVE_BIN : EVENTUALLY_BIN; |
Torne (Richard Coles) | 2a99a7e | 2013-03-28 15:31:22 +0000 | [diff] [blame] | 94 | } |
| 95 | |
Ben Murdoch | ca12bfa | 2013-07-23 11:17:05 +0100 | [diff] [blame] | 96 | // Limit to the number of raster tasks that can be scheduled. |
| 97 | // This is high enough to not cause unnecessary scheduling but |
| 98 | // gives us an insurance that we're not spending a huge amount |
| 99 | // of time scheduling one enormous set of tasks. |
| 100 | const size_t kMaxRasterTasks = 256u; |
| 101 | |
Torne (Richard Coles) | 2a99a7e | 2013-03-28 15:31:22 +0000 | [diff] [blame] | 102 | } // namespace |
| 103 | |
Ben Murdoch | ca12bfa | 2013-07-23 11:17:05 +0100 | [diff] [blame] | 104 | RasterTaskCompletionStats::RasterTaskCompletionStats() |
| 105 | : completed_count(0u), |
| 106 | canceled_count(0u) { |
| 107 | } |
| 108 | |
| 109 | scoped_ptr<base::Value> RasterTaskCompletionStatsAsValue( |
| 110 | const RasterTaskCompletionStats& stats) { |
| 111 | scoped_ptr<base::DictionaryValue> state(new base::DictionaryValue()); |
| 112 | state->SetInteger("completed_count", stats.completed_count); |
| 113 | state->SetInteger("canceled_count", stats.canceled_count); |
| 114 | return state.PassAs<base::Value>(); |
| 115 | } |
| 116 | |
Torne (Richard Coles) | 90dce4d | 2013-05-29 14:40:03 +0100 | [diff] [blame] | 117 | // static |
| 118 | scoped_ptr<TileManager> TileManager::Create( |
Torne (Richard Coles) | 2a99a7e | 2013-03-28 15:31:22 +0000 | [diff] [blame] | 119 | TileManagerClient* client, |
| 120 | ResourceProvider* resource_provider, |
| 121 | size_t num_raster_threads, |
Torne (Richard Coles) | 90dce4d | 2013-05-29 14:40:03 +0100 | [diff] [blame] | 122 | RenderingStatsInstrumentation* rendering_stats_instrumentation, |
| 123 | bool use_map_image) { |
Torne (Richard Coles) | 868fa2f | 2013-06-11 10:57:03 +0100 | [diff] [blame] | 124 | return make_scoped_ptr( |
| 125 | new TileManager(client, |
| 126 | resource_provider, |
| 127 | use_map_image ? |
| 128 | ImageRasterWorkerPool::Create( |
| 129 | resource_provider, num_raster_threads) : |
| 130 | PixelBufferRasterWorkerPool::Create( |
| 131 | resource_provider, num_raster_threads), |
| 132 | num_raster_threads, |
Torne (Richard Coles) | 7d4cd47 | 2013-06-19 11:58:07 +0100 | [diff] [blame] | 133 | rendering_stats_instrumentation, |
| 134 | resource_provider->best_texture_format())); |
Torne (Richard Coles) | 90dce4d | 2013-05-29 14:40:03 +0100 | [diff] [blame] | 135 | } |
| 136 | |
| 137 | TileManager::TileManager( |
| 138 | TileManagerClient* client, |
| 139 | ResourceProvider* resource_provider, |
| 140 | scoped_ptr<RasterWorkerPool> raster_worker_pool, |
| 141 | size_t num_raster_threads, |
Torne (Richard Coles) | 7d4cd47 | 2013-06-19 11:58:07 +0100 | [diff] [blame] | 142 | RenderingStatsInstrumentation* rendering_stats_instrumentation, |
| 143 | GLenum texture_format) |
Torne (Richard Coles) | 2a99a7e | 2013-03-28 15:31:22 +0000 | [diff] [blame] | 144 | : client_(client), |
| 145 | resource_pool_(ResourcePool::Create(resource_provider)), |
Torne (Richard Coles) | 90dce4d | 2013-05-29 14:40:03 +0100 | [diff] [blame] | 146 | raster_worker_pool_(raster_worker_pool.Pass()), |
Ben Murdoch | ca12bfa | 2013-07-23 11:17:05 +0100 | [diff] [blame] | 147 | all_tiles_that_need_to_be_rasterized_have_memory_(true), |
Ben Murdoch | 7dbb3d5 | 2013-07-17 14:55:54 +0100 | [diff] [blame] | 148 | all_tiles_required_for_activation_have_memory_(true), |
Ben Murdoch | ca12bfa | 2013-07-23 11:17:05 +0100 | [diff] [blame] | 149 | all_tiles_required_for_activation_have_been_initialized_(true), |
Torne (Richard Coles) | 2a99a7e | 2013-03-28 15:31:22 +0000 | [diff] [blame] | 150 | ever_exceeded_memory_budget_(false), |
Torne (Richard Coles) | c2e0dbd | 2013-05-09 18:35:53 +0100 | [diff] [blame] | 151 | rendering_stats_instrumentation_(rendering_stats_instrumentation), |
Torne (Richard Coles) | 7d4cd47 | 2013-06-19 11:58:07 +0100 | [diff] [blame] | 152 | did_initialize_visible_tile_(false), |
| 153 | texture_format_(texture_format) { |
| 154 | raster_worker_pool_->SetClient(this); |
Torne (Richard Coles) | 2a99a7e | 2013-03-28 15:31:22 +0000 | [diff] [blame] | 155 | } |
| 156 | |
| 157 | TileManager::~TileManager() { |
| 158 | // Reset global state and manage. This should cause |
| 159 | // our memory usage to drop to zero. |
| 160 | global_state_ = GlobalStateThatImpactsTilePriority(); |
Ben Murdoch | 7dbb3d5 | 2013-07-17 14:55:54 +0100 | [diff] [blame] | 161 | |
Ben Murdoch | bb1529c | 2013-08-08 10:24:53 +0100 | [diff] [blame^] | 162 | // Clear |prioritized_tiles_| so that tiles kept alive by it can be freed. |
| 163 | prioritized_tiles_.Clear(); |
Ben Murdoch | 7dbb3d5 | 2013-07-17 14:55:54 +0100 | [diff] [blame] | 164 | DCHECK_EQ(0u, tiles_.size()); |
| 165 | |
| 166 | TileVector empty; |
| 167 | ScheduleTasks(empty); |
| 168 | |
Torne (Richard Coles) | 2a99a7e | 2013-03-28 15:31:22 +0000 | [diff] [blame] | 169 | // This should finish all pending tasks and release any uninitialized |
| 170 | // resources. |
Torne (Richard Coles) | c2e0dbd | 2013-05-09 18:35:53 +0100 | [diff] [blame] | 171 | raster_worker_pool_->Shutdown(); |
Torne (Richard Coles) | 868fa2f | 2013-06-11 10:57:03 +0100 | [diff] [blame] | 172 | raster_worker_pool_->CheckForCompletedTasks(); |
Torne (Richard Coles) | 2a99a7e | 2013-03-28 15:31:22 +0000 | [diff] [blame] | 173 | } |
| 174 | |
| 175 | void TileManager::SetGlobalState( |
| 176 | const GlobalStateThatImpactsTilePriority& global_state) { |
| 177 | global_state_ = global_state; |
Torne (Richard Coles) | a36e592 | 2013-08-05 13:57:33 +0100 | [diff] [blame] | 178 | resource_pool_->SetMemoryUsageLimits( |
Torne (Richard Coles) | c2e0dbd | 2013-05-09 18:35:53 +0100 | [diff] [blame] | 179 | global_state_.memory_limit_in_bytes, |
Torne (Richard Coles) | a36e592 | 2013-08-05 13:57:33 +0100 | [diff] [blame] | 180 | global_state_.unused_memory_limit_in_bytes, |
| 181 | global_state_.num_resources_limit); |
Torne (Richard Coles) | 2a99a7e | 2013-03-28 15:31:22 +0000 | [diff] [blame] | 182 | } |
| 183 | |
| 184 | void TileManager::RegisterTile(Tile* tile) { |
Torne (Richard Coles) | 90dce4d | 2013-05-29 14:40:03 +0100 | [diff] [blame] | 185 | DCHECK(!tile->required_for_activation()); |
Ben Murdoch | 7dbb3d5 | 2013-07-17 14:55:54 +0100 | [diff] [blame] | 186 | DCHECK(tiles_.find(tile->id()) == tiles_.end()); |
| 187 | |
| 188 | tiles_[tile->id()] = tile; |
Torne (Richard Coles) | 2a99a7e | 2013-03-28 15:31:22 +0000 | [diff] [blame] | 189 | } |
| 190 | |
| 191 | void TileManager::UnregisterTile(Tile* tile) { |
Torne (Richard Coles) | 2a99a7e | 2013-03-28 15:31:22 +0000 | [diff] [blame] | 192 | FreeResourcesForTile(tile); |
Ben Murdoch | 7dbb3d5 | 2013-07-17 14:55:54 +0100 | [diff] [blame] | 193 | |
| 194 | DCHECK(tiles_.find(tile->id()) != tiles_.end()); |
| 195 | tiles_.erase(tile->id()); |
Torne (Richard Coles) | 2a99a7e | 2013-03-28 15:31:22 +0000 | [diff] [blame] | 196 | } |
| 197 | |
Torne (Richard Coles) | 7d4cd47 | 2013-06-19 11:58:07 +0100 | [diff] [blame] | 198 | bool TileManager::ShouldForceTasksRequiredForActivationToComplete() const { |
Ben Murdoch | eb525c5 | 2013-07-10 11:40:50 +0100 | [diff] [blame] | 199 | return GlobalState().tree_priority != SMOOTHNESS_TAKES_PRIORITY; |
| 200 | } |
| 201 | |
Ben Murdoch | 7dbb3d5 | 2013-07-17 14:55:54 +0100 | [diff] [blame] | 202 | void TileManager::DidFinishRunningTasks() { |
| 203 | TRACE_EVENT0("cc", "TileManager::DidFinishRunningTasks"); |
| 204 | |
Ben Murdoch | eb525c5 | 2013-07-10 11:40:50 +0100 | [diff] [blame] | 205 | // When OOM, keep re-assigning memory until we reach a steady state |
| 206 | // where top-priority tiles are initialized. |
Ben Murdoch | ca12bfa | 2013-07-23 11:17:05 +0100 | [diff] [blame] | 207 | if (all_tiles_that_need_to_be_rasterized_have_memory_) |
Ben Murdoch | eb525c5 | 2013-07-10 11:40:50 +0100 | [diff] [blame] | 208 | return; |
| 209 | |
| 210 | raster_worker_pool_->CheckForCompletedTasks(); |
| 211 | |
Ben Murdoch | 7dbb3d5 | 2013-07-17 14:55:54 +0100 | [diff] [blame] | 212 | TileVector tiles_that_need_to_be_rasterized; |
Ben Murdoch | bb1529c | 2013-08-08 10:24:53 +0100 | [diff] [blame^] | 213 | AssignGpuMemoryToTiles(&prioritized_tiles_, |
| 214 | &tiles_that_need_to_be_rasterized); |
Ben Murdoch | eb525c5 | 2013-07-10 11:40:50 +0100 | [diff] [blame] | 215 | |
Ben Murdoch | 7dbb3d5 | 2013-07-17 14:55:54 +0100 | [diff] [blame] | 216 | // |tiles_that_need_to_be_rasterized| will be empty when we reach a |
Ben Murdoch | eb525c5 | 2013-07-10 11:40:50 +0100 | [diff] [blame] | 217 | // steady memory state. Keep scheduling tasks until we reach this state. |
Ben Murdoch | 7dbb3d5 | 2013-07-17 14:55:54 +0100 | [diff] [blame] | 218 | if (!tiles_that_need_to_be_rasterized.empty()) { |
| 219 | ScheduleTasks(tiles_that_need_to_be_rasterized); |
Ben Murdoch | eb525c5 | 2013-07-10 11:40:50 +0100 | [diff] [blame] | 220 | return; |
| 221 | } |
| 222 | |
Ben Murdoch | 7dbb3d5 | 2013-07-17 14:55:54 +0100 | [diff] [blame] | 223 | // Use on-demand raster for any required-for-activation tiles that have not |
| 224 | // been been assigned memory after reaching a steady memory state. This |
| 225 | // ensures that we activate even when OOM. |
| 226 | for (TileMap::iterator it = tiles_.begin(); it != tiles_.end(); ++it) { |
| 227 | Tile* tile = it->second; |
Ben Murdoch | eb525c5 | 2013-07-10 11:40:50 +0100 | [diff] [blame] | 228 | ManagedTileState& mts = tile->managed_state(); |
Ben Murdoch | 7dbb3d5 | 2013-07-17 14:55:54 +0100 | [diff] [blame] | 229 | ManagedTileState::TileVersion& tile_version = |
| 230 | mts.tile_versions[mts.raster_mode]; |
Ben Murdoch | eb525c5 | 2013-07-10 11:40:50 +0100 | [diff] [blame] | 231 | |
Ben Murdoch | 7dbb3d5 | 2013-07-17 14:55:54 +0100 | [diff] [blame] | 232 | if (tile->required_for_activation() && !tile_version.IsReadyToDraw()) |
| 233 | tile_version.set_rasterize_on_demand(); |
| 234 | } |
| 235 | |
Ben Murdoch | eb525c5 | 2013-07-10 11:40:50 +0100 | [diff] [blame] | 236 | client_->NotifyReadyToActivate(); |
| 237 | } |
| 238 | |
Ben Murdoch | 7dbb3d5 | 2013-07-17 14:55:54 +0100 | [diff] [blame] | 239 | void TileManager::DidFinishRunningTasksRequiredForActivation() { |
Ben Murdoch | eb525c5 | 2013-07-10 11:40:50 +0100 | [diff] [blame] | 240 | // This is only a true indication that all tiles required for |
| 241 | // activation are initialized when no tiles are OOM. We need to |
| 242 | // wait for DidFinishRunningTasks() to be called, try to re-assign |
| 243 | // memory and in worst case use on-demand raster when tiles |
| 244 | // required for activation are OOM. |
Ben Murdoch | 7dbb3d5 | 2013-07-17 14:55:54 +0100 | [diff] [blame] | 245 | if (!all_tiles_required_for_activation_have_memory_) |
Ben Murdoch | eb525c5 | 2013-07-10 11:40:50 +0100 | [diff] [blame] | 246 | return; |
| 247 | |
| 248 | client_->NotifyReadyToActivate(); |
Torne (Richard Coles) | 7d4cd47 | 2013-06-19 11:58:07 +0100 | [diff] [blame] | 249 | } |
| 250 | |
Ben Murdoch | bb1529c | 2013-08-08 10:24:53 +0100 | [diff] [blame^] | 251 | void TileManager::GetTilesWithAssignedBins(PrioritizedTileSet* tiles) { |
Torne (Richard Coles) | a36e592 | 2013-08-05 13:57:33 +0100 | [diff] [blame] | 252 | TRACE_EVENT0("cc", "TileManager::GetTilesWithAssignedBins"); |
| 253 | |
Torne (Richard Coles) | a36e592 | 2013-08-05 13:57:33 +0100 | [diff] [blame] | 254 | const TileMemoryLimitPolicy memory_policy = global_state_.memory_limit_policy; |
Torne (Richard Coles) | 2a99a7e | 2013-03-28 15:31:22 +0000 | [diff] [blame] | 255 | const TreePriority tree_priority = global_state_.tree_priority; |
Torne (Richard Coles) | 2a99a7e | 2013-03-28 15:31:22 +0000 | [diff] [blame] | 256 | |
Torne (Richard Coles) | 2a99a7e | 2013-03-28 15:31:22 +0000 | [diff] [blame] | 257 | // For each tree, bin into different categories of tiles. |
Torne (Richard Coles) | a36e592 | 2013-08-05 13:57:33 +0100 | [diff] [blame] | 258 | for (TileMap::const_iterator it = tiles_.begin(); it != tiles_.end(); ++it) { |
| 259 | Tile* tile = it->second; |
Torne (Richard Coles) | 2a99a7e | 2013-03-28 15:31:22 +0000 | [diff] [blame] | 260 | ManagedTileState& mts = tile->managed_state(); |
| 261 | |
| 262 | TilePriority prio[NUM_BIN_PRIORITIES]; |
| 263 | switch (tree_priority) { |
| 264 | case SAME_PRIORITY_FOR_BOTH_TREES: |
| 265 | prio[HIGH_PRIORITY_BIN] = prio[LOW_PRIORITY_BIN] = |
| 266 | tile->combined_priority(); |
| 267 | break; |
| 268 | case SMOOTHNESS_TAKES_PRIORITY: |
| 269 | prio[HIGH_PRIORITY_BIN] = tile->priority(ACTIVE_TREE); |
| 270 | prio[LOW_PRIORITY_BIN] = tile->priority(PENDING_TREE); |
| 271 | break; |
| 272 | case NEW_CONTENT_TAKES_PRIORITY: |
| 273 | prio[HIGH_PRIORITY_BIN] = tile->priority(PENDING_TREE); |
| 274 | prio[LOW_PRIORITY_BIN] = tile->priority(ACTIVE_TREE); |
| 275 | break; |
| 276 | } |
| 277 | |
Ben Murdoch | bb1529c | 2013-08-08 10:24:53 +0100 | [diff] [blame^] | 278 | bool tile_is_ready_to_draw = tile->IsReadyToDraw(); |
| 279 | bool tile_is_active = |
| 280 | tile_is_ready_to_draw || |
| 281 | !mts.tile_versions[mts.raster_mode].raster_task_.is_null(); |
| 282 | |
Torne (Richard Coles) | 2a99a7e | 2013-03-28 15:31:22 +0000 | [diff] [blame] | 283 | mts.resolution = prio[HIGH_PRIORITY_BIN].resolution; |
| 284 | mts.time_to_needed_in_seconds = |
| 285 | prio[HIGH_PRIORITY_BIN].time_to_visible_in_seconds; |
| 286 | mts.distance_to_visible_in_pixels = |
| 287 | prio[HIGH_PRIORITY_BIN].distance_to_visible_in_pixels; |
Torne (Richard Coles) | 90dce4d | 2013-05-29 14:40:03 +0100 | [diff] [blame] | 288 | mts.required_for_activation = |
| 289 | prio[HIGH_PRIORITY_BIN].required_for_activation; |
Torne (Richard Coles) | 2a99a7e | 2013-03-28 15:31:22 +0000 | [diff] [blame] | 290 | |
Ben Murdoch | bb1529c | 2013-08-08 10:24:53 +0100 | [diff] [blame^] | 291 | mts.bin[HIGH_PRIORITY_BIN] = |
| 292 | BinFromTilePriority(prio[HIGH_PRIORITY_BIN], |
| 293 | tree_priority, |
| 294 | tile_is_ready_to_draw, |
| 295 | tile_is_active); |
| 296 | mts.bin[LOW_PRIORITY_BIN] = |
| 297 | BinFromTilePriority(prio[LOW_PRIORITY_BIN], |
| 298 | tree_priority, |
| 299 | tile_is_ready_to_draw, |
| 300 | tile_is_active); |
| 301 | mts.gpu_memmgr_stats_bin = |
| 302 | BinFromTilePriority(tile->combined_priority(), |
| 303 | tree_priority, |
| 304 | tile_is_ready_to_draw, |
| 305 | tile_is_active); |
| 306 | |
| 307 | ManagedTileBin active_bin = |
| 308 | BinFromTilePriority(tile->priority(ACTIVE_TREE), |
| 309 | tree_priority, |
| 310 | tile_is_ready_to_draw, |
| 311 | tile_is_active); |
| 312 | mts.tree_bin[ACTIVE_TREE] = kBinPolicyMap[memory_policy][active_bin]; |
| 313 | |
| 314 | ManagedTileBin pending_bin = |
| 315 | BinFromTilePriority(tile->priority(PENDING_TREE), |
| 316 | tree_priority, |
| 317 | tile_is_ready_to_draw, |
| 318 | tile_is_active); |
| 319 | mts.tree_bin[PENDING_TREE] = kBinPolicyMap[memory_policy][pending_bin]; |
Torne (Richard Coles) | 2a99a7e | 2013-03-28 15:31:22 +0000 | [diff] [blame] | 320 | |
| 321 | for (int i = 0; i < NUM_BIN_PRIORITIES; ++i) |
Torne (Richard Coles) | a36e592 | 2013-08-05 13:57:33 +0100 | [diff] [blame] | 322 | mts.bin[i] = kBinPolicyMap[memory_policy][mts.bin[i]]; |
Ben Murdoch | 7dbb3d5 | 2013-07-17 14:55:54 +0100 | [diff] [blame] | 323 | |
| 324 | mts.visible_and_ready_to_draw = |
Ben Murdoch | bb1529c | 2013-08-08 10:24:53 +0100 | [diff] [blame^] | 325 | mts.tree_bin[ACTIVE_TREE] == NOW_AND_READY_TO_DRAW_BIN; |
Torne (Richard Coles) | a36e592 | 2013-08-05 13:57:33 +0100 | [diff] [blame] | 326 | |
Ben Murdoch | bb1529c | 2013-08-08 10:24:53 +0100 | [diff] [blame^] | 327 | if (mts.is_in_never_bin_on_both_trees()) { |
Torne (Richard Coles) | a36e592 | 2013-08-05 13:57:33 +0100 | [diff] [blame] | 328 | FreeResourcesForTile(tile); |
Ben Murdoch | bb1529c | 2013-08-08 10:24:53 +0100 | [diff] [blame^] | 329 | continue; |
| 330 | } |
| 331 | |
| 332 | // Note that if the tile is visible_and_ready_to_draw, then we always want |
| 333 | // the priority to be NOW_AND_READY_TO_DRAW_BIN, even if HIGH_PRIORITY_BIN |
| 334 | // is something different. The reason for this is that if we're prioritizing |
| 335 | // the pending tree, we still want visible tiles to take the highest |
| 336 | // priority. |
| 337 | ManagedTileBin priority_bin = mts.visible_and_ready_to_draw |
| 338 | ? NOW_AND_READY_TO_DRAW_BIN |
| 339 | : mts.bin[HIGH_PRIORITY_BIN]; |
| 340 | |
| 341 | // Insert the tile into a priority set. |
| 342 | tiles->InsertTile(tile, priority_bin); |
Torne (Richard Coles) | 2a99a7e | 2013-03-28 15:31:22 +0000 | [diff] [blame] | 343 | } |
Torne (Richard Coles) | c2e0dbd | 2013-05-09 18:35:53 +0100 | [diff] [blame] | 344 | } |
| 345 | |
Ben Murdoch | bb1529c | 2013-08-08 10:24:53 +0100 | [diff] [blame^] | 346 | void TileManager::GetPrioritizedTileSet(PrioritizedTileSet* tiles) { |
| 347 | TRACE_EVENT0("cc", "TileManager::GetPrioritizedTileSet"); |
Ben Murdoch | 7dbb3d5 | 2013-07-17 14:55:54 +0100 | [diff] [blame] | 348 | |
Torne (Richard Coles) | a36e592 | 2013-08-05 13:57:33 +0100 | [diff] [blame] | 349 | GetTilesWithAssignedBins(tiles); |
Ben Murdoch | bb1529c | 2013-08-08 10:24:53 +0100 | [diff] [blame^] | 350 | tiles->Sort(); |
Torne (Richard Coles) | c2e0dbd | 2013-05-09 18:35:53 +0100 | [diff] [blame] | 351 | } |
| 352 | |
| 353 | void TileManager::ManageTiles() { |
| 354 | TRACE_EVENT0("cc", "TileManager::ManageTiles"); |
Ben Murdoch | 7dbb3d5 | 2013-07-17 14:55:54 +0100 | [diff] [blame] | 355 | |
Ben Murdoch | bb1529c | 2013-08-08 10:24:53 +0100 | [diff] [blame^] | 356 | // Clear |prioritized_tiles_| so that tiles kept alive by it can be freed. |
| 357 | prioritized_tiles_.Clear(); |
Ben Murdoch | 7dbb3d5 | 2013-07-17 14:55:54 +0100 | [diff] [blame] | 358 | |
Ben Murdoch | bb1529c | 2013-08-08 10:24:53 +0100 | [diff] [blame^] | 359 | GetPrioritizedTileSet(&prioritized_tiles_); |
Ben Murdoch | 7dbb3d5 | 2013-07-17 14:55:54 +0100 | [diff] [blame] | 360 | |
| 361 | TileVector tiles_that_need_to_be_rasterized; |
Ben Murdoch | bb1529c | 2013-08-08 10:24:53 +0100 | [diff] [blame^] | 362 | AssignGpuMemoryToTiles(&prioritized_tiles_, |
| 363 | &tiles_that_need_to_be_rasterized); |
Torne (Richard Coles) | 7d4cd47 | 2013-06-19 11:58:07 +0100 | [diff] [blame] | 364 | CleanUpUnusedImageDecodeTasks(); |
| 365 | |
Torne (Richard Coles) | b2df76e | 2013-05-13 16:52:09 +0100 | [diff] [blame] | 366 | TRACE_EVENT_INSTANT1( |
| 367 | "cc", "DidManage", TRACE_EVENT_SCOPE_THREAD, |
| 368 | "state", TracedValue::FromValue(BasicStateAsValue().release())); |
Torne (Richard Coles) | 2a99a7e | 2013-03-28 15:31:22 +0000 | [diff] [blame] | 369 | |
Torne (Richard Coles) | 868fa2f | 2013-06-11 10:57:03 +0100 | [diff] [blame] | 370 | // Finally, schedule rasterizer tasks. |
Ben Murdoch | 7dbb3d5 | 2013-07-17 14:55:54 +0100 | [diff] [blame] | 371 | ScheduleTasks(tiles_that_need_to_be_rasterized); |
Torne (Richard Coles) | 2a99a7e | 2013-03-28 15:31:22 +0000 | [diff] [blame] | 372 | } |
| 373 | |
Ben Murdoch | ca12bfa | 2013-07-23 11:17:05 +0100 | [diff] [blame] | 374 | bool TileManager::UpdateVisibleTiles() { |
| 375 | TRACE_EVENT0("cc", "TileManager::UpdateVisibleTiles"); |
| 376 | |
Torne (Richard Coles) | 868fa2f | 2013-06-11 10:57:03 +0100 | [diff] [blame] | 377 | raster_worker_pool_->CheckForCompletedTasks(); |
Ben Murdoch | eb525c5 | 2013-07-10 11:40:50 +0100 | [diff] [blame] | 378 | |
Ben Murdoch | ca12bfa | 2013-07-23 11:17:05 +0100 | [diff] [blame] | 379 | TRACE_EVENT_INSTANT1( |
| 380 | "cc", "DidUpdateVisibleTiles", TRACE_EVENT_SCOPE_THREAD, |
| 381 | "stats", TracedValue::FromValue( |
| 382 | RasterTaskCompletionStatsAsValue( |
| 383 | update_visible_tiles_stats_).release())); |
| 384 | update_visible_tiles_stats_ = RasterTaskCompletionStats(); |
| 385 | |
| 386 | bool did_initialize_visible_tile = did_initialize_visible_tile_; |
| 387 | did_initialize_visible_tile_ = false; |
| 388 | return did_initialize_visible_tile; |
Torne (Richard Coles) | 2a99a7e | 2013-03-28 15:31:22 +0000 | [diff] [blame] | 389 | } |
| 390 | |
| 391 | void TileManager::GetMemoryStats( |
| 392 | size_t* memory_required_bytes, |
| 393 | size_t* memory_nice_to_have_bytes, |
| 394 | size_t* memory_used_bytes) const { |
| 395 | *memory_required_bytes = 0; |
| 396 | *memory_nice_to_have_bytes = 0; |
Torne (Richard Coles) | 868fa2f | 2013-06-11 10:57:03 +0100 | [diff] [blame] | 397 | *memory_used_bytes = resource_pool_->acquired_memory_usage_bytes(); |
Ben Murdoch | 7dbb3d5 | 2013-07-17 14:55:54 +0100 | [diff] [blame] | 398 | for (TileMap::const_iterator it = tiles_.begin(); |
Torne (Richard Coles) | c2e0dbd | 2013-05-09 18:35:53 +0100 | [diff] [blame] | 399 | it != tiles_.end(); |
| 400 | ++it) { |
Ben Murdoch | 7dbb3d5 | 2013-07-17 14:55:54 +0100 | [diff] [blame] | 401 | const Tile* tile = it->second; |
Torne (Richard Coles) | 868fa2f | 2013-06-11 10:57:03 +0100 | [diff] [blame] | 402 | const ManagedTileState& mts = tile->managed_state(); |
| 403 | |
Ben Murdoch | 7dbb3d5 | 2013-07-17 14:55:54 +0100 | [diff] [blame] | 404 | const ManagedTileState::TileVersion& tile_version = |
| 405 | tile->GetTileVersionForDrawing(); |
| 406 | if (tile_version.IsReadyToDraw() && |
| 407 | !tile_version.requires_resource()) |
Torne (Richard Coles) | 2a99a7e | 2013-03-28 15:31:22 +0000 | [diff] [blame] | 408 | continue; |
| 409 | |
| 410 | size_t tile_bytes = tile->bytes_consumed_if_allocated(); |
Ben Murdoch | bb1529c | 2013-08-08 10:24:53 +0100 | [diff] [blame^] | 411 | if ((mts.gpu_memmgr_stats_bin == NOW_BIN) || |
| 412 | (mts.gpu_memmgr_stats_bin == NOW_AND_READY_TO_DRAW_BIN)) |
Torne (Richard Coles) | 2a99a7e | 2013-03-28 15:31:22 +0000 | [diff] [blame] | 413 | *memory_required_bytes += tile_bytes; |
| 414 | if (mts.gpu_memmgr_stats_bin != NEVER_BIN) |
| 415 | *memory_nice_to_have_bytes += tile_bytes; |
Torne (Richard Coles) | 2a99a7e | 2013-03-28 15:31:22 +0000 | [diff] [blame] | 416 | } |
| 417 | } |
| 418 | |
| 419 | scoped_ptr<base::Value> TileManager::BasicStateAsValue() const { |
| 420 | scoped_ptr<base::DictionaryValue> state(new base::DictionaryValue()); |
Torne (Richard Coles) | c2e0dbd | 2013-05-09 18:35:53 +0100 | [diff] [blame] | 421 | state->SetInteger("tile_count", tiles_.size()); |
Torne (Richard Coles) | 2a99a7e | 2013-03-28 15:31:22 +0000 | [diff] [blame] | 422 | state->Set("global_state", global_state_.AsValue().release()); |
| 423 | state->Set("memory_requirements", GetMemoryRequirementsAsValue().release()); |
| 424 | return state.PassAs<base::Value>(); |
| 425 | } |
| 426 | |
| 427 | scoped_ptr<base::Value> TileManager::AllTilesAsValue() const { |
| 428 | scoped_ptr<base::ListValue> state(new base::ListValue()); |
Ben Murdoch | 7dbb3d5 | 2013-07-17 14:55:54 +0100 | [diff] [blame] | 429 | for (TileMap::const_iterator it = tiles_.begin(); |
Torne (Richard Coles) | c2e0dbd | 2013-05-09 18:35:53 +0100 | [diff] [blame] | 430 | it != tiles_.end(); |
Torne (Richard Coles) | 2a99a7e | 2013-03-28 15:31:22 +0000 | [diff] [blame] | 431 | it++) { |
Ben Murdoch | 7dbb3d5 | 2013-07-17 14:55:54 +0100 | [diff] [blame] | 432 | state->Append(it->second->AsValue().release()); |
Torne (Richard Coles) | 2a99a7e | 2013-03-28 15:31:22 +0000 | [diff] [blame] | 433 | } |
| 434 | return state.PassAs<base::Value>(); |
| 435 | } |
| 436 | |
| 437 | scoped_ptr<base::Value> TileManager::GetMemoryRequirementsAsValue() const { |
| 438 | scoped_ptr<base::DictionaryValue> requirements( |
| 439 | new base::DictionaryValue()); |
| 440 | |
| 441 | size_t memory_required_bytes; |
| 442 | size_t memory_nice_to_have_bytes; |
| 443 | size_t memory_used_bytes; |
| 444 | GetMemoryStats(&memory_required_bytes, |
| 445 | &memory_nice_to_have_bytes, |
| 446 | &memory_used_bytes); |
| 447 | requirements->SetInteger("memory_required_bytes", memory_required_bytes); |
| 448 | requirements->SetInteger("memory_nice_to_have_bytes", |
| 449 | memory_nice_to_have_bytes); |
| 450 | requirements->SetInteger("memory_used_bytes", memory_used_bytes); |
| 451 | return requirements.PassAs<base::Value>(); |
| 452 | } |
| 453 | |
Torne (Richard Coles) | 7d4cd47 | 2013-06-19 11:58:07 +0100 | [diff] [blame] | 454 | RasterMode TileManager::DetermineRasterMode(const Tile* tile) const { |
Torne (Richard Coles) | 868fa2f | 2013-06-11 10:57:03 +0100 | [diff] [blame] | 455 | DCHECK(tile); |
| 456 | DCHECK(tile->picture_pile()); |
Torne (Richard Coles) | 2a99a7e | 2013-03-28 15:31:22 +0000 | [diff] [blame] | 457 | |
Ben Murdoch | eb525c5 | 2013-07-10 11:40:50 +0100 | [diff] [blame] | 458 | const ManagedTileState& mts = tile->managed_state(); |
| 459 | RasterMode current_mode = mts.raster_mode; |
Torne (Richard Coles) | 868fa2f | 2013-06-11 10:57:03 +0100 | [diff] [blame] | 460 | |
Ben Murdoch | eb525c5 | 2013-07-10 11:40:50 +0100 | [diff] [blame] | 461 | RasterMode raster_mode = HIGH_QUALITY_RASTER_MODE; |
Torne (Richard Coles) | 868fa2f | 2013-06-11 10:57:03 +0100 | [diff] [blame] | 462 | if (tile->managed_state().resolution == LOW_RESOLUTION) |
| 463 | raster_mode = LOW_QUALITY_RASTER_MODE; |
Ben Murdoch | eb525c5 | 2013-07-10 11:40:50 +0100 | [diff] [blame] | 464 | else if (tile->can_use_lcd_text()) |
Torne (Richard Coles) | 868fa2f | 2013-06-11 10:57:03 +0100 | [diff] [blame] | 465 | raster_mode = HIGH_QUALITY_RASTER_MODE; |
Ben Murdoch | eb525c5 | 2013-07-10 11:40:50 +0100 | [diff] [blame] | 466 | else if (mts.tile_versions[current_mode].has_text_ || |
| 467 | !mts.tile_versions[current_mode].IsReadyToDraw()) |
| 468 | raster_mode = HIGH_QUALITY_NO_LCD_RASTER_MODE; |
Torne (Richard Coles) | 868fa2f | 2013-06-11 10:57:03 +0100 | [diff] [blame] | 469 | |
Ben Murdoch | eb525c5 | 2013-07-10 11:40:50 +0100 | [diff] [blame] | 470 | return std::min(raster_mode, current_mode); |
Torne (Richard Coles) | 2a99a7e | 2013-03-28 15:31:22 +0000 | [diff] [blame] | 471 | } |
| 472 | |
Ben Murdoch | 7dbb3d5 | 2013-07-17 14:55:54 +0100 | [diff] [blame] | 473 | void TileManager::AssignGpuMemoryToTiles( |
Ben Murdoch | bb1529c | 2013-08-08 10:24:53 +0100 | [diff] [blame^] | 474 | PrioritizedTileSet* tiles, |
Ben Murdoch | 7dbb3d5 | 2013-07-17 14:55:54 +0100 | [diff] [blame] | 475 | TileVector* tiles_that_need_to_be_rasterized) { |
Torne (Richard Coles) | 2a99a7e | 2013-03-28 15:31:22 +0000 | [diff] [blame] | 476 | TRACE_EVENT0("cc", "TileManager::AssignGpuMemoryToTiles"); |
Torne (Richard Coles) | 2a99a7e | 2013-03-28 15:31:22 +0000 | [diff] [blame] | 477 | |
| 478 | // Now give memory out to the tiles until we're out, and build |
| 479 | // the needs-to-be-rasterized queue. |
Torne (Richard Coles) | 868fa2f | 2013-06-11 10:57:03 +0100 | [diff] [blame] | 480 | size_t bytes_releasable = 0; |
Torne (Richard Coles) | a36e592 | 2013-08-05 13:57:33 +0100 | [diff] [blame] | 481 | size_t resources_releasable = 0; |
Ben Murdoch | bb1529c | 2013-08-08 10:24:53 +0100 | [diff] [blame^] | 482 | for (PrioritizedTileSet::PriorityIterator it(tiles); |
| 483 | it; |
Torne (Richard Coles) | c2e0dbd | 2013-05-09 18:35:53 +0100 | [diff] [blame] | 484 | ++it) { |
Ben Murdoch | bb1529c | 2013-08-08 10:24:53 +0100 | [diff] [blame^] | 485 | const Tile* tile = *it; |
Torne (Richard Coles) | 868fa2f | 2013-06-11 10:57:03 +0100 | [diff] [blame] | 486 | const ManagedTileState& mts = tile->managed_state(); |
| 487 | for (int mode = 0; mode < NUM_RASTER_MODES; ++mode) { |
Torne (Richard Coles) | a36e592 | 2013-08-05 13:57:33 +0100 | [diff] [blame] | 488 | if (mts.tile_versions[mode].resource_) { |
Torne (Richard Coles) | 868fa2f | 2013-06-11 10:57:03 +0100 | [diff] [blame] | 489 | bytes_releasable += tile->bytes_consumed_if_allocated(); |
Torne (Richard Coles) | a36e592 | 2013-08-05 13:57:33 +0100 | [diff] [blame] | 490 | resources_releasable++; |
| 491 | } |
Torne (Richard Coles) | 868fa2f | 2013-06-11 10:57:03 +0100 | [diff] [blame] | 492 | } |
Torne (Richard Coles) | 2a99a7e | 2013-03-28 15:31:22 +0000 | [diff] [blame] | 493 | } |
| 494 | |
Ben Murdoch | ca12bfa | 2013-07-23 11:17:05 +0100 | [diff] [blame] | 495 | all_tiles_that_need_to_be_rasterized_have_memory_ = true; |
Ben Murdoch | 7dbb3d5 | 2013-07-17 14:55:54 +0100 | [diff] [blame] | 496 | all_tiles_required_for_activation_have_memory_ = true; |
Ben Murdoch | ca12bfa | 2013-07-23 11:17:05 +0100 | [diff] [blame] | 497 | all_tiles_required_for_activation_have_been_initialized_ = true; |
Ben Murdoch | 7dbb3d5 | 2013-07-17 14:55:54 +0100 | [diff] [blame] | 498 | |
Torne (Richard Coles) | 868fa2f | 2013-06-11 10:57:03 +0100 | [diff] [blame] | 499 | // Cast to prevent overflow. |
| 500 | int64 bytes_available = |
| 501 | static_cast<int64>(bytes_releasable) + |
| 502 | static_cast<int64>(global_state_.memory_limit_in_bytes) - |
| 503 | static_cast<int64>(resource_pool_->acquired_memory_usage_bytes()); |
Torne (Richard Coles) | a36e592 | 2013-08-05 13:57:33 +0100 | [diff] [blame] | 504 | int resources_available = resources_releasable + |
| 505 | global_state_.num_resources_limit - |
| 506 | resource_pool_->NumResources(); |
Torne (Richard Coles) | 868fa2f | 2013-06-11 10:57:03 +0100 | [diff] [blame] | 507 | |
Torne (Richard Coles) | 2a99a7e | 2013-03-28 15:31:22 +0000 | [diff] [blame] | 508 | size_t bytes_allocatable = |
Torne (Richard Coles) | 868fa2f | 2013-06-11 10:57:03 +0100 | [diff] [blame] | 509 | std::max(static_cast<int64>(0), bytes_available); |
Torne (Richard Coles) | a36e592 | 2013-08-05 13:57:33 +0100 | [diff] [blame] | 510 | size_t resources_allocatable = std::max(0, resources_available); |
Torne (Richard Coles) | 868fa2f | 2013-06-11 10:57:03 +0100 | [diff] [blame] | 511 | |
Ben Murdoch | eb525c5 | 2013-07-10 11:40:50 +0100 | [diff] [blame] | 512 | size_t bytes_that_exceeded_memory_budget = 0; |
Torne (Richard Coles) | 2a99a7e | 2013-03-28 15:31:22 +0000 | [diff] [blame] | 513 | size_t bytes_left = bytes_allocatable; |
Torne (Richard Coles) | a36e592 | 2013-08-05 13:57:33 +0100 | [diff] [blame] | 514 | size_t resources_left = resources_allocatable; |
Ben Murdoch | ca12bfa | 2013-07-23 11:17:05 +0100 | [diff] [blame] | 515 | bool oomed = false; |
Ben Murdoch | 2385ea3 | 2013-08-06 11:01:04 +0100 | [diff] [blame] | 516 | |
| 517 | unsigned schedule_priority = 1u; |
Ben Murdoch | bb1529c | 2013-08-08 10:24:53 +0100 | [diff] [blame^] | 518 | for (PrioritizedTileSet::PriorityIterator it(tiles); |
| 519 | it; |
Torne (Richard Coles) | 2a99a7e | 2013-03-28 15:31:22 +0000 | [diff] [blame] | 520 | ++it) { |
Ben Murdoch | bb1529c | 2013-08-08 10:24:53 +0100 | [diff] [blame^] | 521 | Tile* tile = *it; |
Torne (Richard Coles) | 2a99a7e | 2013-03-28 15:31:22 +0000 | [diff] [blame] | 522 | ManagedTileState& mts = tile->managed_state(); |
Torne (Richard Coles) | 868fa2f | 2013-06-11 10:57:03 +0100 | [diff] [blame] | 523 | |
Ben Murdoch | 2385ea3 | 2013-08-06 11:01:04 +0100 | [diff] [blame] | 524 | mts.scheduled_priority = schedule_priority++; |
| 525 | |
Ben Murdoch | eb525c5 | 2013-07-10 11:40:50 +0100 | [diff] [blame] | 526 | mts.raster_mode = DetermineRasterMode(tile); |
Torne (Richard Coles) | 868fa2f | 2013-06-11 10:57:03 +0100 | [diff] [blame] | 527 | |
| 528 | ManagedTileState::TileVersion& tile_version = |
| 529 | mts.tile_versions[mts.raster_mode]; |
Torne (Richard Coles) | c2e0dbd | 2013-05-09 18:35:53 +0100 | [diff] [blame] | 530 | |
Torne (Richard Coles) | 90dce4d | 2013-05-29 14:40:03 +0100 | [diff] [blame] | 531 | // If this tile doesn't need a resource, then nothing to do. |
| 532 | if (!tile_version.requires_resource()) |
| 533 | continue; |
| 534 | |
Torne (Richard Coles) | c2e0dbd | 2013-05-09 18:35:53 +0100 | [diff] [blame] | 535 | // If the tile is not needed, free it up. |
| 536 | if (mts.is_in_never_bin_on_both_trees()) { |
Torne (Richard Coles) | 2a99a7e | 2013-03-28 15:31:22 +0000 | [diff] [blame] | 537 | FreeResourcesForTile(tile); |
| 538 | continue; |
| 539 | } |
Torne (Richard Coles) | 868fa2f | 2013-06-11 10:57:03 +0100 | [diff] [blame] | 540 | |
| 541 | size_t tile_bytes = 0; |
Torne (Richard Coles) | a36e592 | 2013-08-05 13:57:33 +0100 | [diff] [blame] | 542 | size_t tile_resources = 0; |
Torne (Richard Coles) | 868fa2f | 2013-06-11 10:57:03 +0100 | [diff] [blame] | 543 | |
| 544 | // It costs to maintain a resource. |
| 545 | for (int mode = 0; mode < NUM_RASTER_MODES; ++mode) { |
Torne (Richard Coles) | a36e592 | 2013-08-05 13:57:33 +0100 | [diff] [blame] | 546 | if (mts.tile_versions[mode].resource_) { |
Torne (Richard Coles) | 868fa2f | 2013-06-11 10:57:03 +0100 | [diff] [blame] | 547 | tile_bytes += tile->bytes_consumed_if_allocated(); |
Torne (Richard Coles) | a36e592 | 2013-08-05 13:57:33 +0100 | [diff] [blame] | 548 | tile_resources++; |
| 549 | } |
Torne (Richard Coles) | 868fa2f | 2013-06-11 10:57:03 +0100 | [diff] [blame] | 550 | } |
| 551 | |
Ben Murdoch | ca12bfa | 2013-07-23 11:17:05 +0100 | [diff] [blame] | 552 | // Allow lower priority tiles with initialized resources to keep |
| 553 | // their memory by only assigning memory to new raster tasks if |
| 554 | // they can be scheduled. |
| 555 | if (tiles_that_need_to_be_rasterized->size() < kMaxRasterTasks) { |
| 556 | // If we don't have the required version, and it's not in flight |
| 557 | // then we'll have to pay to create a new task. |
Torne (Richard Coles) | a36e592 | 2013-08-05 13:57:33 +0100 | [diff] [blame] | 558 | if (!tile_version.resource_ && tile_version.raster_task_.is_null()) { |
Ben Murdoch | ca12bfa | 2013-07-23 11:17:05 +0100 | [diff] [blame] | 559 | tile_bytes += tile->bytes_consumed_if_allocated(); |
Torne (Richard Coles) | a36e592 | 2013-08-05 13:57:33 +0100 | [diff] [blame] | 560 | tile_resources++; |
| 561 | } |
Ben Murdoch | ca12bfa | 2013-07-23 11:17:05 +0100 | [diff] [blame] | 562 | } |
Torne (Richard Coles) | 868fa2f | 2013-06-11 10:57:03 +0100 | [diff] [blame] | 563 | |
Torne (Richard Coles) | c2e0dbd | 2013-05-09 18:35:53 +0100 | [diff] [blame] | 564 | // Tile is OOM. |
Torne (Richard Coles) | a36e592 | 2013-08-05 13:57:33 +0100 | [diff] [blame] | 565 | if (tile_bytes > bytes_left || tile_resources > resources_left) { |
Torne (Richard Coles) | 868fa2f | 2013-06-11 10:57:03 +0100 | [diff] [blame] | 566 | FreeResourcesForTile(tile); |
Ben Murdoch | 7dbb3d5 | 2013-07-17 14:55:54 +0100 | [diff] [blame] | 567 | |
Ben Murdoch | ca12bfa | 2013-07-23 11:17:05 +0100 | [diff] [blame] | 568 | // This tile was already on screen and now its resources have been |
Ben Murdoch | 7dbb3d5 | 2013-07-17 14:55:54 +0100 | [diff] [blame] | 569 | // released. In order to prevent checkerboarding, set this tile as |
| 570 | // rasterize on demand immediately. |
| 571 | if (mts.visible_and_ready_to_draw) |
| 572 | tile_version.set_rasterize_on_demand(); |
| 573 | |
Ben Murdoch | ca12bfa | 2013-07-23 11:17:05 +0100 | [diff] [blame] | 574 | oomed = true; |
Ben Murdoch | eb525c5 | 2013-07-10 11:40:50 +0100 | [diff] [blame] | 575 | bytes_that_exceeded_memory_budget += tile_bytes; |
Ben Murdoch | ca12bfa | 2013-07-23 11:17:05 +0100 | [diff] [blame] | 576 | } else { |
| 577 | bytes_left -= tile_bytes; |
Torne (Richard Coles) | a36e592 | 2013-08-05 13:57:33 +0100 | [diff] [blame] | 578 | resources_left -= tile_resources; |
Ben Murdoch | ca12bfa | 2013-07-23 11:17:05 +0100 | [diff] [blame] | 579 | |
| 580 | if (tile_version.resource_) |
| 581 | continue; |
Torne (Richard Coles) | 2a99a7e | 2013-03-28 15:31:22 +0000 | [diff] [blame] | 582 | } |
Torne (Richard Coles) | 868fa2f | 2013-06-11 10:57:03 +0100 | [diff] [blame] | 583 | |
Ben Murdoch | ca12bfa | 2013-07-23 11:17:05 +0100 | [diff] [blame] | 584 | DCHECK(!tile_version.resource_); |
Torne (Richard Coles) | 868fa2f | 2013-06-11 10:57:03 +0100 | [diff] [blame] | 585 | |
Ben Murdoch | ca12bfa | 2013-07-23 11:17:05 +0100 | [diff] [blame] | 586 | if (tile->required_for_activation()) |
| 587 | all_tiles_required_for_activation_have_been_initialized_ = false; |
| 588 | |
| 589 | // Tile shouldn't be rasterized if |tiles_that_need_to_be_rasterized| |
| 590 | // has reached it's limit or we've failed to assign gpu memory to this |
| 591 | // or any higher priority tile. Preventing tiles that fit into memory |
| 592 | // budget to be rasterized when higher priority tile is oom is |
| 593 | // important for two reasons: |
Torne (Richard Coles) | 868fa2f | 2013-06-11 10:57:03 +0100 | [diff] [blame] | 594 | // 1. Tile size should not impact raster priority. |
Ben Murdoch | ca12bfa | 2013-07-23 11:17:05 +0100 | [diff] [blame] | 595 | // 2. Tiles with existing raster task could otherwise incorrectly |
| 596 | // be added as they are not affected by |bytes_allocatable|. |
| 597 | if (oomed || tiles_that_need_to_be_rasterized->size() >= kMaxRasterTasks) { |
| 598 | all_tiles_that_need_to_be_rasterized_have_memory_ = false; |
Ben Murdoch | 7dbb3d5 | 2013-07-17 14:55:54 +0100 | [diff] [blame] | 599 | if (tile->required_for_activation()) |
| 600 | all_tiles_required_for_activation_have_memory_ = false; |
Torne (Richard Coles) | 868fa2f | 2013-06-11 10:57:03 +0100 | [diff] [blame] | 601 | continue; |
Ben Murdoch | 7dbb3d5 | 2013-07-17 14:55:54 +0100 | [diff] [blame] | 602 | } |
Torne (Richard Coles) | 868fa2f | 2013-06-11 10:57:03 +0100 | [diff] [blame] | 603 | |
Ben Murdoch | ca12bfa | 2013-07-23 11:17:05 +0100 | [diff] [blame] | 604 | tiles_that_need_to_be_rasterized->push_back(tile); |
Torne (Richard Coles) | c2e0dbd | 2013-05-09 18:35:53 +0100 | [diff] [blame] | 605 | } |
| 606 | |
Ben Murdoch | eb525c5 | 2013-07-10 11:40:50 +0100 | [diff] [blame] | 607 | ever_exceeded_memory_budget_ |= bytes_that_exceeded_memory_budget > 0; |
Torne (Richard Coles) | 2a99a7e | 2013-03-28 15:31:22 +0000 | [diff] [blame] | 608 | if (ever_exceeded_memory_budget_) { |
| 609 | TRACE_COUNTER_ID2("cc", "over_memory_budget", this, |
| 610 | "budget", global_state_.memory_limit_in_bytes, |
Ben Murdoch | eb525c5 | 2013-07-10 11:40:50 +0100 | [diff] [blame] | 611 | "over", bytes_that_exceeded_memory_budget); |
Torne (Richard Coles) | 2a99a7e | 2013-03-28 15:31:22 +0000 | [diff] [blame] | 612 | } |
| 613 | memory_stats_from_last_assign_.total_budget_in_bytes = |
| 614 | global_state_.memory_limit_in_bytes; |
| 615 | memory_stats_from_last_assign_.bytes_allocated = |
| 616 | bytes_allocatable - bytes_left; |
Torne (Richard Coles) | 868fa2f | 2013-06-11 10:57:03 +0100 | [diff] [blame] | 617 | memory_stats_from_last_assign_.bytes_unreleasable = |
| 618 | bytes_allocatable - bytes_releasable; |
Torne (Richard Coles) | 2a99a7e | 2013-03-28 15:31:22 +0000 | [diff] [blame] | 619 | memory_stats_from_last_assign_.bytes_over = |
Ben Murdoch | eb525c5 | 2013-07-10 11:40:50 +0100 | [diff] [blame] | 620 | bytes_that_exceeded_memory_budget; |
| 621 | } |
| 622 | |
Torne (Richard Coles) | 7d4cd47 | 2013-06-19 11:58:07 +0100 | [diff] [blame] | 623 | void TileManager::CleanUpUnusedImageDecodeTasks() { |
| 624 | // Calculate a set of layers that are used by at least one tile. |
| 625 | base::hash_set<int> used_layers; |
Ben Murdoch | 7dbb3d5 | 2013-07-17 14:55:54 +0100 | [diff] [blame] | 626 | for (TileMap::iterator it = tiles_.begin(); it != tiles_.end(); ++it) |
| 627 | used_layers.insert(it->second->layer_id()); |
Torne (Richard Coles) | 7d4cd47 | 2013-06-19 11:58:07 +0100 | [diff] [blame] | 628 | |
| 629 | // Now calculate the set of layers in |image_decode_tasks_| that are not used |
| 630 | // by any tile. |
| 631 | std::vector<int> unused_layers; |
| 632 | for (LayerPixelRefTaskMap::iterator it = image_decode_tasks_.begin(); |
| 633 | it != image_decode_tasks_.end(); |
| 634 | ++it) { |
| 635 | if (used_layers.find(it->first) == used_layers.end()) |
| 636 | unused_layers.push_back(it->first); |
| 637 | } |
| 638 | |
| 639 | // Erase unused layers from |image_decode_tasks_|. |
| 640 | for (std::vector<int>::iterator it = unused_layers.begin(); |
| 641 | it != unused_layers.end(); |
| 642 | ++it) { |
| 643 | image_decode_tasks_.erase(*it); |
| 644 | } |
| 645 | } |
| 646 | |
| 647 | void TileManager::FreeResourceForTile(Tile* tile, RasterMode mode) { |
Torne (Richard Coles) | 868fa2f | 2013-06-11 10:57:03 +0100 | [diff] [blame] | 648 | ManagedTileState& mts = tile->managed_state(); |
| 649 | if (mts.tile_versions[mode].resource_) { |
| 650 | resource_pool_->ReleaseResource( |
| 651 | mts.tile_versions[mode].resource_.Pass()); |
| 652 | } |
Torne (Richard Coles) | 2a99a7e | 2013-03-28 15:31:22 +0000 | [diff] [blame] | 653 | } |
| 654 | |
| 655 | void TileManager::FreeResourcesForTile(Tile* tile) { |
Torne (Richard Coles) | 868fa2f | 2013-06-11 10:57:03 +0100 | [diff] [blame] | 656 | for (int mode = 0; mode < NUM_RASTER_MODES; ++mode) { |
Torne (Richard Coles) | 7d4cd47 | 2013-06-19 11:58:07 +0100 | [diff] [blame] | 657 | FreeResourceForTile(tile, static_cast<RasterMode>(mode)); |
Torne (Richard Coles) | 2a99a7e | 2013-03-28 15:31:22 +0000 | [diff] [blame] | 658 | } |
| 659 | } |
| 660 | |
Torne (Richard Coles) | 868fa2f | 2013-06-11 10:57:03 +0100 | [diff] [blame] | 661 | void TileManager::FreeUnusedResourcesForTile(Tile* tile) { |
Ben Murdoch | 7dbb3d5 | 2013-07-17 14:55:54 +0100 | [diff] [blame] | 662 | DCHECK(tile->IsReadyToDraw()); |
| 663 | ManagedTileState& mts = tile->managed_state(); |
| 664 | RasterMode used_mode = HIGH_QUALITY_NO_LCD_RASTER_MODE; |
Torne (Richard Coles) | 868fa2f | 2013-06-11 10:57:03 +0100 | [diff] [blame] | 665 | for (int mode = 0; mode < NUM_RASTER_MODES; ++mode) { |
Ben Murdoch | 7dbb3d5 | 2013-07-17 14:55:54 +0100 | [diff] [blame] | 666 | if (mts.tile_versions[mode].IsReadyToDraw()) { |
| 667 | used_mode = static_cast<RasterMode>(mode); |
| 668 | break; |
| 669 | } |
| 670 | } |
| 671 | |
| 672 | for (int mode = 0; mode < NUM_RASTER_MODES; ++mode) { |
| 673 | if (mode != used_mode) |
Torne (Richard Coles) | 7d4cd47 | 2013-06-19 11:58:07 +0100 | [diff] [blame] | 674 | FreeResourceForTile(tile, static_cast<RasterMode>(mode)); |
Torne (Richard Coles) | 2a99a7e | 2013-03-28 15:31:22 +0000 | [diff] [blame] | 675 | } |
| 676 | } |
| 677 | |
Ben Murdoch | 7dbb3d5 | 2013-07-17 14:55:54 +0100 | [diff] [blame] | 678 | void TileManager::ScheduleTasks( |
| 679 | const TileVector& tiles_that_need_to_be_rasterized) { |
Ben Murdoch | eb525c5 | 2013-07-10 11:40:50 +0100 | [diff] [blame] | 680 | TRACE_EVENT1("cc", "TileManager::ScheduleTasks", |
Ben Murdoch | 7dbb3d5 | 2013-07-17 14:55:54 +0100 | [diff] [blame] | 681 | "count", tiles_that_need_to_be_rasterized.size()); |
Torne (Richard Coles) | 868fa2f | 2013-06-11 10:57:03 +0100 | [diff] [blame] | 682 | RasterWorkerPool::RasterTask::Queue tasks; |
Torne (Richard Coles) | 2a99a7e | 2013-03-28 15:31:22 +0000 | [diff] [blame] | 683 | |
Torne (Richard Coles) | 868fa2f | 2013-06-11 10:57:03 +0100 | [diff] [blame] | 684 | // Build a new task queue containing all task currently needed. Tasks |
| 685 | // are added in order of priority, highest priority task first. |
Ben Murdoch | 7dbb3d5 | 2013-07-17 14:55:54 +0100 | [diff] [blame] | 686 | for (TileVector::const_iterator it = tiles_that_need_to_be_rasterized.begin(); |
| 687 | it != tiles_that_need_to_be_rasterized.end(); |
Torne (Richard Coles) | 868fa2f | 2013-06-11 10:57:03 +0100 | [diff] [blame] | 688 | ++it) { |
| 689 | Tile* tile = *it; |
| 690 | ManagedTileState& mts = tile->managed_state(); |
| 691 | ManagedTileState::TileVersion& tile_version = |
| 692 | mts.tile_versions[mts.raster_mode]; |
| 693 | |
| 694 | DCHECK(tile_version.requires_resource()); |
| 695 | DCHECK(!tile_version.resource_); |
| 696 | |
| 697 | if (tile_version.raster_task_.is_null()) |
Torne (Richard Coles) | 7d4cd47 | 2013-06-19 11:58:07 +0100 | [diff] [blame] | 698 | tile_version.raster_task_ = CreateRasterTask(tile); |
Torne (Richard Coles) | 868fa2f | 2013-06-11 10:57:03 +0100 | [diff] [blame] | 699 | |
Torne (Richard Coles) | 7d4cd47 | 2013-06-19 11:58:07 +0100 | [diff] [blame] | 700 | tasks.Append(tile_version.raster_task_, tile->required_for_activation()); |
Torne (Richard Coles) | 868fa2f | 2013-06-11 10:57:03 +0100 | [diff] [blame] | 701 | } |
| 702 | |
| 703 | // Schedule running of |tasks|. This replaces any previously |
| 704 | // scheduled tasks and effectively cancels all tasks not present |
| 705 | // in |tasks|. |
| 706 | raster_worker_pool_->ScheduleTasks(&tasks); |
| 707 | } |
| 708 | |
| 709 | RasterWorkerPool::Task TileManager::CreateImageDecodeTask( |
| 710 | Tile* tile, skia::LazyPixelRef* pixel_ref) { |
Torne (Richard Coles) | 7d4cd47 | 2013-06-19 11:58:07 +0100 | [diff] [blame] | 711 | return RasterWorkerPool::CreateImageDecodeTask( |
| 712 | pixel_ref, |
| 713 | tile->layer_id(), |
| 714 | rendering_stats_instrumentation_, |
Torne (Richard Coles) | 2a99a7e | 2013-03-28 15:31:22 +0000 | [diff] [blame] | 715 | base::Bind(&TileManager::OnImageDecodeTaskCompleted, |
| 716 | base::Unretained(this), |
Torne (Richard Coles) | 7d4cd47 | 2013-06-19 11:58:07 +0100 | [diff] [blame] | 717 | tile->layer_id(), |
| 718 | base::Unretained(pixel_ref))); |
Torne (Richard Coles) | 2a99a7e | 2013-03-28 15:31:22 +0000 | [diff] [blame] | 719 | } |
| 720 | |
Torne (Richard Coles) | 7d4cd47 | 2013-06-19 11:58:07 +0100 | [diff] [blame] | 721 | RasterWorkerPool::RasterTask TileManager::CreateRasterTask(Tile* tile) { |
Torne (Richard Coles) | 868fa2f | 2013-06-11 10:57:03 +0100 | [diff] [blame] | 722 | ManagedTileState& mts = tile->managed_state(); |
| 723 | |
| 724 | scoped_ptr<ResourcePool::Resource> resource = |
Torne (Richard Coles) | 7d4cd47 | 2013-06-19 11:58:07 +0100 | [diff] [blame] | 725 | resource_pool_->AcquireResource(tile->tile_size_.size(), |
| 726 | texture_format_); |
Torne (Richard Coles) | 868fa2f | 2013-06-11 10:57:03 +0100 | [diff] [blame] | 727 | const Resource* const_resource = resource.get(); |
| 728 | |
Torne (Richard Coles) | 868fa2f | 2013-06-11 10:57:03 +0100 | [diff] [blame] | 729 | // Create and queue all image decode tasks that this tile depends on. |
| 730 | RasterWorkerPool::Task::Set decode_tasks; |
Torne (Richard Coles) | 7d4cd47 | 2013-06-19 11:58:07 +0100 | [diff] [blame] | 731 | PixelRefTaskMap& existing_pixel_refs = image_decode_tasks_[tile->layer_id()]; |
Torne (Richard Coles) | 868fa2f | 2013-06-11 10:57:03 +0100 | [diff] [blame] | 732 | for (PicturePileImpl::PixelRefIterator iter(tile->content_rect(), |
| 733 | tile->contents_scale(), |
| 734 | tile->picture_pile()); |
| 735 | iter; ++iter) { |
| 736 | skia::LazyPixelRef* pixel_ref = *iter; |
| 737 | uint32_t id = pixel_ref->getGenerationID(); |
| 738 | |
| 739 | // Append existing image decode task if available. |
Torne (Richard Coles) | 7d4cd47 | 2013-06-19 11:58:07 +0100 | [diff] [blame] | 740 | PixelRefTaskMap::iterator decode_task_it = existing_pixel_refs.find(id); |
| 741 | if (decode_task_it != existing_pixel_refs.end()) { |
Torne (Richard Coles) | 868fa2f | 2013-06-11 10:57:03 +0100 | [diff] [blame] | 742 | decode_tasks.Insert(decode_task_it->second); |
| 743 | continue; |
| 744 | } |
| 745 | |
Torne (Richard Coles) | 868fa2f | 2013-06-11 10:57:03 +0100 | [diff] [blame] | 746 | // Create and append new image decode task for this pixel ref. |
| 747 | RasterWorkerPool::Task decode_task = CreateImageDecodeTask( |
| 748 | tile, pixel_ref); |
| 749 | decode_tasks.Insert(decode_task); |
Torne (Richard Coles) | 7d4cd47 | 2013-06-19 11:58:07 +0100 | [diff] [blame] | 750 | existing_pixel_refs[id] = decode_task; |
Torne (Richard Coles) | 868fa2f | 2013-06-11 10:57:03 +0100 | [diff] [blame] | 751 | } |
| 752 | |
Torne (Richard Coles) | 7d4cd47 | 2013-06-19 11:58:07 +0100 | [diff] [blame] | 753 | return RasterWorkerPool::CreateRasterTask( |
Torne (Richard Coles) | 868fa2f | 2013-06-11 10:57:03 +0100 | [diff] [blame] | 754 | const_resource, |
Torne (Richard Coles) | 7d4cd47 | 2013-06-19 11:58:07 +0100 | [diff] [blame] | 755 | tile->picture_pile(), |
| 756 | tile->content_rect(), |
| 757 | tile->contents_scale(), |
| 758 | mts.raster_mode, |
Ben Murdoch | 7dbb3d5 | 2013-07-17 14:55:54 +0100 | [diff] [blame] | 759 | mts.tree_bin[PENDING_TREE] == NOW_BIN, |
| 760 | mts.resolution, |
| 761 | tile->layer_id(), |
| 762 | static_cast<const void *>(tile), |
| 763 | tile->source_frame_number(), |
Torne (Richard Coles) | 7d4cd47 | 2013-06-19 11:58:07 +0100 | [diff] [blame] | 764 | rendering_stats_instrumentation_, |
Torne (Richard Coles) | 868fa2f | 2013-06-11 10:57:03 +0100 | [diff] [blame] | 765 | base::Bind(&TileManager::OnRasterTaskCompleted, |
| 766 | base::Unretained(this), |
Ben Murdoch | 7dbb3d5 | 2013-07-17 14:55:54 +0100 | [diff] [blame] | 767 | tile->id(), |
Torne (Richard Coles) | 868fa2f | 2013-06-11 10:57:03 +0100 | [diff] [blame] | 768 | base::Passed(&resource), |
Torne (Richard Coles) | 7d4cd47 | 2013-06-19 11:58:07 +0100 | [diff] [blame] | 769 | mts.raster_mode), |
Ben Murdoch | eb525c5 | 2013-07-10 11:40:50 +0100 | [diff] [blame] | 770 | &decode_tasks); |
Torne (Richard Coles) | 7d4cd47 | 2013-06-19 11:58:07 +0100 | [diff] [blame] | 771 | } |
| 772 | |
| 773 | void TileManager::OnImageDecodeTaskCompleted( |
| 774 | int layer_id, |
| 775 | skia::LazyPixelRef* pixel_ref, |
| 776 | bool was_canceled) { |
| 777 | // If the task was canceled, we need to clean it up |
| 778 | // from |image_decode_tasks_|. |
| 779 | if (!was_canceled) |
| 780 | return; |
| 781 | |
| 782 | LayerPixelRefTaskMap::iterator layer_it = |
| 783 | image_decode_tasks_.find(layer_id); |
| 784 | |
| 785 | if (layer_it == image_decode_tasks_.end()) |
| 786 | return; |
| 787 | |
| 788 | PixelRefTaskMap& pixel_ref_tasks = layer_it->second; |
| 789 | PixelRefTaskMap::iterator task_it = |
| 790 | pixel_ref_tasks.find(pixel_ref->getGenerationID()); |
| 791 | |
| 792 | if (task_it != pixel_ref_tasks.end()) |
| 793 | pixel_ref_tasks.erase(task_it); |
Torne (Richard Coles) | 868fa2f | 2013-06-11 10:57:03 +0100 | [diff] [blame] | 794 | } |
| 795 | |
Torne (Richard Coles) | 2a99a7e | 2013-03-28 15:31:22 +0000 | [diff] [blame] | 796 | void TileManager::OnRasterTaskCompleted( |
Ben Murdoch | 7dbb3d5 | 2013-07-17 14:55:54 +0100 | [diff] [blame] | 797 | Tile::Id tile_id, |
Torne (Richard Coles) | 2a99a7e | 2013-03-28 15:31:22 +0000 | [diff] [blame] | 798 | scoped_ptr<ResourcePool::Resource> resource, |
Torne (Richard Coles) | 7d4cd47 | 2013-06-19 11:58:07 +0100 | [diff] [blame] | 799 | RasterMode raster_mode, |
| 800 | const PicturePileImpl::Analysis& analysis, |
Torne (Richard Coles) | 868fa2f | 2013-06-11 10:57:03 +0100 | [diff] [blame] | 801 | bool was_canceled) { |
Ben Murdoch | 7dbb3d5 | 2013-07-17 14:55:54 +0100 | [diff] [blame] | 802 | TileMap::iterator it = tiles_.find(tile_id); |
| 803 | if (it == tiles_.end()) { |
Ben Murdoch | ca12bfa | 2013-07-23 11:17:05 +0100 | [diff] [blame] | 804 | ++update_visible_tiles_stats_.canceled_count; |
Ben Murdoch | 7dbb3d5 | 2013-07-17 14:55:54 +0100 | [diff] [blame] | 805 | resource_pool_->ReleaseResource(resource.Pass()); |
| 806 | return; |
| 807 | } |
| 808 | |
| 809 | Tile* tile = it->second; |
Torne (Richard Coles) | 868fa2f | 2013-06-11 10:57:03 +0100 | [diff] [blame] | 810 | ManagedTileState& mts = tile->managed_state(); |
| 811 | ManagedTileState::TileVersion& tile_version = |
| 812 | mts.tile_versions[raster_mode]; |
| 813 | DCHECK(!tile_version.raster_task_.is_null()); |
| 814 | tile_version.raster_task_.Reset(); |
Torne (Richard Coles) | 2a99a7e | 2013-03-28 15:31:22 +0000 | [diff] [blame] | 815 | |
Torne (Richard Coles) | 868fa2f | 2013-06-11 10:57:03 +0100 | [diff] [blame] | 816 | if (was_canceled) { |
Ben Murdoch | ca12bfa | 2013-07-23 11:17:05 +0100 | [diff] [blame] | 817 | ++update_visible_tiles_stats_.canceled_count; |
Torne (Richard Coles) | c2e0dbd | 2013-05-09 18:35:53 +0100 | [diff] [blame] | 818 | resource_pool_->ReleaseResource(resource.Pass()); |
Torne (Richard Coles) | c2e0dbd | 2013-05-09 18:35:53 +0100 | [diff] [blame] | 819 | return; |
| 820 | } |
Torne (Richard Coles) | 2a99a7e | 2013-03-28 15:31:22 +0000 | [diff] [blame] | 821 | |
Ben Murdoch | ca12bfa | 2013-07-23 11:17:05 +0100 | [diff] [blame] | 822 | ++update_visible_tiles_stats_.completed_count; |
| 823 | |
Torne (Richard Coles) | 7d4cd47 | 2013-06-19 11:58:07 +0100 | [diff] [blame] | 824 | tile_version.set_has_text(analysis.has_text); |
| 825 | if (analysis.is_solid_color) { |
| 826 | tile_version.set_solid_color(analysis.solid_color); |
Torne (Richard Coles) | 2a99a7e | 2013-03-28 15:31:22 +0000 | [diff] [blame] | 827 | resource_pool_->ReleaseResource(resource.Pass()); |
Torne (Richard Coles) | 868fa2f | 2013-06-11 10:57:03 +0100 | [diff] [blame] | 828 | } else { |
Ben Murdoch | 7dbb3d5 | 2013-07-17 14:55:54 +0100 | [diff] [blame] | 829 | tile_version.set_use_resource(); |
Torne (Richard Coles) | 868fa2f | 2013-06-11 10:57:03 +0100 | [diff] [blame] | 830 | tile_version.resource_ = resource.Pass(); |
Torne (Richard Coles) | 2a99a7e | 2013-03-28 15:31:22 +0000 | [diff] [blame] | 831 | } |
Torne (Richard Coles) | 868fa2f | 2013-06-11 10:57:03 +0100 | [diff] [blame] | 832 | |
Ben Murdoch | 7dbb3d5 | 2013-07-17 14:55:54 +0100 | [diff] [blame] | 833 | FreeUnusedResourcesForTile(tile); |
Torne (Richard Coles) | 2a99a7e | 2013-03-28 15:31:22 +0000 | [diff] [blame] | 834 | if (tile->priority(ACTIVE_TREE).distance_to_visible_in_pixels == 0) |
Torne (Richard Coles) | c2e0dbd | 2013-05-09 18:35:53 +0100 | [diff] [blame] | 835 | did_initialize_visible_tile_ = true; |
Torne (Richard Coles) | 2a99a7e | 2013-03-28 15:31:22 +0000 | [diff] [blame] | 836 | } |
| 837 | |
Torne (Richard Coles) | 2a99a7e | 2013-03-28 15:31:22 +0000 | [diff] [blame] | 838 | } // namespace cc |