| 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 #include <set> | 8 #include <set> |
| 9 | 9 |
| 10 #include "base/bind.h" | 10 #include "base/bind.h" |
| (...skipping 13 matching lines...) Expand all Loading... |
| 24 | 24 |
| 25 const char* kRasterThreadNamePrefix = "CompositorRaster"; | 25 const char* kRasterThreadNamePrefix = "CompositorRaster"; |
| 26 | 26 |
| 27 const int kMaxRasterThreads = 64; | 27 const int kMaxRasterThreads = 64; |
| 28 const int kDefaultNumberOfRasterThreads = 1; | 28 const int kDefaultNumberOfRasterThreads = 1; |
| 29 | 29 |
| 30 // Allow two pending raster tasks per thread. This keeps resource usage | 30 // Allow two pending raster tasks per thread. This keeps resource usage |
| 31 // low while making sure raster threads aren't unnecessarily idle. | 31 // low while making sure raster threads aren't unnecessarily idle. |
| 32 const int kNumPendingRasterTasksPerThread = 2; | 32 const int kNumPendingRasterTasksPerThread = 2; |
| 33 | 33 |
| 34 // Determine bin based on three categories of tiles: things we need now, |
| 35 // things we need soon, and eventually. |
| 36 cc::TileManagerBin BinFromTilePriority(const cc::TilePriority& prio) { |
| 37 |
| 38 // The amount of time for which we want to have prepainting coverage. |
| 39 const double prepainting_window_time_seconds = 1.0; |
| 40 const double backfling_guard_distance_pixels = 314.0; |
| 41 |
| 42 if (prio.time_to_needed_in_seconds() == std::numeric_limits<float>::max()) |
| 43 return cc::NEVER_BIN; |
| 44 |
| 45 if (prio.resolution == cc::NON_IDEAL_RESOLUTION) |
| 46 return cc::EVENTUALLY_BIN; |
| 47 |
| 48 if (prio.time_to_needed_in_seconds() == 0 || |
| 49 prio.distance_to_visible_in_pixels < backfling_guard_distance_pixels) |
| 50 return cc::NOW_BIN; |
| 51 |
| 52 if (prio.time_to_needed_in_seconds() < prepainting_window_time_seconds) |
| 53 return cc::SOON_BIN; |
| 54 |
| 55 return cc::EVENTUALLY_BIN; |
| 56 } |
| 57 |
| 34 } // namespace | 58 } // namespace |
| 35 | 59 |
| 36 namespace cc { | 60 namespace cc { |
| 37 | 61 |
| 38 class RasterThread : public base::Thread { | 62 class RasterThread : public base::Thread { |
| 39 public: | 63 public: |
| 40 RasterThread(const std::string name) | 64 RasterThread(const std::string name) |
| 41 : base::Thread(name.c_str()), | 65 : base::Thread(name.c_str()), |
| 42 num_pending_tasks_(0) { | 66 num_pending_tasks_(0) { |
| 43 Start(); | 67 Start(); |
| (...skipping 98 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 142 check_for_completed_set_pixels_pending_(false) { | 166 check_for_completed_set_pixels_pending_(false) { |
| 143 // Initialize all threads. | 167 // Initialize all threads. |
| 144 const std::string thread_name_prefix = kRasterThreadNamePrefix; | 168 const std::string thread_name_prefix = kRasterThreadNamePrefix; |
| 145 while (raster_threads_.size() < num_raster_threads) { | 169 while (raster_threads_.size() < num_raster_threads) { |
| 146 int thread_number = raster_threads_.size() + 1; | 170 int thread_number = raster_threads_.size() + 1; |
| 147 scoped_ptr<RasterThread> thread = make_scoped_ptr( | 171 scoped_ptr<RasterThread> thread = make_scoped_ptr( |
| 148 new RasterThread(thread_name_prefix + | 172 new RasterThread(thread_name_prefix + |
| 149 StringPrintf("Worker%d", thread_number).c_str())); | 173 StringPrintf("Worker%d", thread_number).c_str())); |
| 150 raster_threads_.append(thread.Pass()); | 174 raster_threads_.append(thread.Pass()); |
| 151 } | 175 } |
| 176 |
| 177 ResetBinCounts(); |
| 152 } | 178 } |
| 153 | 179 |
| 154 TileManager::~TileManager() { | 180 TileManager::~TileManager() { |
| 155 // Reset global state and manage. This should cause | 181 // Reset global state and manage. This should cause |
| 156 // our memory usage to drop to zero. | 182 // our memory usage to drop to zero. |
| 157 global_state_ = GlobalStateThatImpactsTilePriority(); | 183 global_state_ = GlobalStateThatImpactsTilePriority(); |
| 158 AssignGpuMemoryToTiles(); | 184 AssignGpuMemoryToTiles(); |
| 159 // This should finish all pending raster tasks and release any | 185 // This should finish all pending raster tasks and release any |
| 160 // uninitialized resources. | 186 // uninitialized resources. |
| 161 raster_threads_.clear(); | 187 raster_threads_.clear(); |
| (...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 217 return; | 243 return; |
| 218 client_->ScheduleCheckForCompletedSetPixels(); | 244 client_->ScheduleCheckForCompletedSetPixels(); |
| 219 check_for_completed_set_pixels_pending_ = true; | 245 check_for_completed_set_pixels_pending_ = true; |
| 220 } | 246 } |
| 221 | 247 |
| 222 class BinComparator { | 248 class BinComparator { |
| 223 public: | 249 public: |
| 224 bool operator() (const Tile* a, const Tile* b) const { | 250 bool operator() (const Tile* a, const Tile* b) const { |
| 225 const ManagedTileState& ams = a->managed_state(); | 251 const ManagedTileState& ams = a->managed_state(); |
| 226 const ManagedTileState& bms = b->managed_state(); | 252 const ManagedTileState& bms = b->managed_state(); |
| 227 if (ams.bin != bms.bin) | 253 if (ams.raster_bin != bms.raster_bin) |
| 228 return ams.bin < bms.bin; | 254 return ams.raster_bin < bms.raster_bin; |
| 229 | 255 |
| 230 if (ams.resolution != bms.resolution) | 256 if (ams.resolution != bms.resolution) |
| 231 return ams.resolution < ams.resolution; | 257 return ams.resolution < ams.resolution; |
| 232 | 258 |
| 233 return | 259 return |
| 234 ams.time_to_needed_in_seconds < | 260 ams.time_to_needed_in_seconds < |
| 235 bms.time_to_needed_in_seconds; | 261 bms.time_to_needed_in_seconds; |
| 236 } | 262 } |
| 237 }; | 263 }; |
| 238 | 264 |
| 239 void TileManager::ManageTiles() { | 265 void TileManager::ManageTiles() { |
| 240 TRACE_EVENT0("cc", "TileManager::ManageTiles"); | 266 TRACE_EVENT0("cc", "TileManager::ManageTiles"); |
| 241 manage_tiles_pending_ = false; | 267 manage_tiles_pending_ = false; |
| 242 ++manage_tiles_call_count_; | 268 ++manage_tiles_call_count_; |
| 243 | 269 |
| 244 // The amount of time for which we want to have prepainting coverage. | 270 const bool smoothness_takes_priority = |
| 245 const double prepainting_window_time_seconds = 1.0; | 271 global_state_.smoothness_takes_priority; |
| 246 const double backfling_guard_distance_pixels = 314.0; | |
| 247 | 272 |
| 248 const bool smoothness_takes_priority = global_state_.smoothness_takes_priority
; | 273 // For each tree, bin into different categories of tiles. |
| 249 | |
| 250 // Bin into three categories of tiles: things we need now, things we need soon
, and eventually | |
| 251 for (TileVector::iterator it = tiles_.begin(); it != tiles_.end(); ++it) { | 274 for (TileVector::iterator it = tiles_.begin(); it != tiles_.end(); ++it) { |
| 252 Tile* tile = *it; | 275 Tile* tile = *it; |
| 253 ManagedTileState& mts = tile->managed_state(); | 276 ManagedTileState& mts = tile->managed_state(); |
| 277 mts.bin[ACTIVE_TREE] = BinFromTilePriority(tile->priority(ACTIVE_TREE)); |
| 278 mts.bin[PENDING_TREE] = BinFromTilePriority(tile->priority(PENDING_TREE)); |
| 279 |
| 254 TilePriority prio; | 280 TilePriority prio; |
| 255 if (smoothness_takes_priority) | 281 if (smoothness_takes_priority) |
| 256 prio = tile->priority(ACTIVE_TREE); | 282 prio = tile->priority(ACTIVE_TREE); |
| 257 else | 283 else |
| 258 prio = tile->combined_priority(); | 284 prio = tile->combined_priority(); |
| 259 | 285 |
| 260 mts.resolution = prio.resolution; | 286 mts.resolution = prio.resolution; |
| 261 mts.time_to_needed_in_seconds = prio.time_to_needed_in_seconds(); | 287 mts.time_to_needed_in_seconds = prio.time_to_needed_in_seconds(); |
| 262 | 288 mts.raster_bin = BinFromTilePriority(prio); |
| 263 if (mts.time_to_needed_in_seconds == | |
| 264 std::numeric_limits<float>::max()) { | |
| 265 mts.bin = NEVER_BIN; | |
| 266 continue; | |
| 267 } | |
| 268 | |
| 269 if (mts.resolution == NON_IDEAL_RESOLUTION) { | |
| 270 mts.bin = EVENTUALLY_BIN; | |
| 271 continue; | |
| 272 } | |
| 273 | |
| 274 if (mts.time_to_needed_in_seconds == 0 || | |
| 275 prio.distance_to_visible_in_pixels < backfling_guard_distance_pixels) { | |
| 276 mts.bin = NOW_BIN; | |
| 277 continue; | |
| 278 } | |
| 279 | |
| 280 if (prio.time_to_needed_in_seconds() < prepainting_window_time_seconds) { | |
| 281 mts.bin = SOON_BIN; | |
| 282 continue; | |
| 283 } | |
| 284 | |
| 285 mts.bin = EVENTUALLY_BIN; | |
| 286 } | 289 } |
| 287 | 290 |
| 288 // Memory limit policy works by mapping some bin states to the NEVER bin. | 291 // Memory limit policy works by mapping some bin states to the NEVER bin. |
| 289 TileManagerBin bin_map[NUM_BINS]; | 292 TileManagerBin bin_map[NUM_BINS]; |
| 290 if (global_state_.memory_limit_policy == ALLOW_NOTHING) { | 293 if (global_state_.memory_limit_policy == ALLOW_NOTHING) { |
| 291 bin_map[NOW_BIN] = NEVER_BIN; | 294 bin_map[NOW_BIN] = NEVER_BIN; |
| 292 bin_map[SOON_BIN] = NEVER_BIN; | 295 bin_map[SOON_BIN] = NEVER_BIN; |
| 293 bin_map[EVENTUALLY_BIN] = NEVER_BIN; | 296 bin_map[EVENTUALLY_BIN] = NEVER_BIN; |
| 294 bin_map[NEVER_BIN] = NEVER_BIN; | 297 bin_map[NEVER_BIN] = NEVER_BIN; |
| 295 } else if (global_state_.memory_limit_policy == ALLOW_ABSOLUTE_MINIMUM) { | 298 } else if (global_state_.memory_limit_policy == ALLOW_ABSOLUTE_MINIMUM) { |
| 296 bin_map[NOW_BIN] = NOW_BIN; | 299 bin_map[NOW_BIN] = NOW_BIN; |
| 297 bin_map[SOON_BIN] = NEVER_BIN; | 300 bin_map[SOON_BIN] = NEVER_BIN; |
| 298 bin_map[EVENTUALLY_BIN] = NEVER_BIN; | 301 bin_map[EVENTUALLY_BIN] = NEVER_BIN; |
| 299 bin_map[NEVER_BIN] = NEVER_BIN; | 302 bin_map[NEVER_BIN] = NEVER_BIN; |
| 300 } else if (global_state_.memory_limit_policy == ALLOW_PREPAINT_ONLY) { | 303 } else if (global_state_.memory_limit_policy == ALLOW_PREPAINT_ONLY) { |
| 301 bin_map[NOW_BIN] = NOW_BIN; | 304 bin_map[NOW_BIN] = NOW_BIN; |
| 302 bin_map[SOON_BIN] = SOON_BIN; | 305 bin_map[SOON_BIN] = SOON_BIN; |
| 303 bin_map[EVENTUALLY_BIN] = NEVER_BIN; | 306 bin_map[EVENTUALLY_BIN] = NEVER_BIN; |
| 304 bin_map[NEVER_BIN] = NEVER_BIN; | 307 bin_map[NEVER_BIN] = NEVER_BIN; |
| 305 } else { | 308 } else { |
| 306 bin_map[NOW_BIN] = NOW_BIN; | 309 bin_map[NOW_BIN] = NOW_BIN; |
| 307 bin_map[SOON_BIN] = SOON_BIN; | 310 bin_map[SOON_BIN] = SOON_BIN; |
| 308 bin_map[EVENTUALLY_BIN] = EVENTUALLY_BIN; | 311 bin_map[EVENTUALLY_BIN] = EVENTUALLY_BIN; |
| 309 bin_map[NEVER_BIN] = NEVER_BIN; | 312 bin_map[NEVER_BIN] = NEVER_BIN; |
| 310 } | 313 } |
| 311 for (TileVector::iterator it = tiles_.begin(); it != tiles_.end(); ++it) { | 314 for (TileVector::iterator it = tiles_.begin(); it != tiles_.end(); ++it) { |
| 312 Tile* tile = *it; | 315 Tile* tile = *it; |
| 313 TileManagerBin bin = bin_map[tile->managed_state().bin]; | 316 ManagedTileState& mts = tile->managed_state(); |
| 314 tile->managed_state().bin = bin; | 317 mts.bin[ACTIVE_TREE] = bin_map[mts.bin[ACTIVE_TREE]]; |
| 318 mts.bin[PENDING_TREE] = bin_map[mts.bin[PENDING_TREE]]; |
| 319 mts.raster_bin = bin_map[mts.raster_bin]; |
| 320 } |
| 321 |
| 322 // Update bin counts. |
| 323 ResetBinCounts(); |
| 324 for (TileVector::iterator it = tiles_.begin(); it != tiles_.end(); ++it) { |
| 325 Tile* tile = *it; |
| 326 ManagedTileState& mts = tile->managed_state(); |
| 327 for (int i = 0; i < NUM_TREES; ++i) |
| 328 tiles_in_bin_count_[mts.bin[i]][i]++; |
| 329 |
| 330 // Increment drawable count if GetResourceId() doesn't return 0. |
| 331 if (tile->GetResourceId()) { |
| 332 for (int i = 0; i < NUM_TREES; ++i) |
| 333 drawable_tiles_in_bin_count_[mts.bin[i]][i]++; |
| 334 } |
| 315 } | 335 } |
| 316 | 336 |
| 317 // Sort by bin. | 337 // Sort by bin. |
| 318 std::sort(tiles_.begin(), tiles_.end(), BinComparator()); | 338 std::sort(tiles_.begin(), tiles_.end(), BinComparator()); |
| 319 | 339 |
| 320 // Assign gpu memory and determine what tiles need to be rasterized. | 340 // Assign gpu memory and determine what tiles need to be rasterized. |
| 321 AssignGpuMemoryToTiles(); | 341 AssignGpuMemoryToTiles(); |
| 322 | 342 |
| 323 // Finally, kick the rasterizer. | 343 // Finally, kick the rasterizer. |
| 324 DispatchMoreTasks(); | 344 DispatchMoreTasks(); |
| (...skipping 15 matching lines...) Expand all Loading... |
| 340 | 360 |
| 341 // It's now safe to release the pixel buffer. | 361 // It's now safe to release the pixel buffer. |
| 342 resource_pool_->resource_provider()->releasePixelBuffer( | 362 resource_pool_->resource_provider()->releasePixelBuffer( |
| 343 tile->managed_state().resource->id()); | 363 tile->managed_state().resource->id()); |
| 344 | 364 |
| 345 DidFinishTileInitialization(tile); | 365 DidFinishTileInitialization(tile); |
| 346 tiles_with_pending_set_pixels_.pop(); | 366 tiles_with_pending_set_pixels_.pop(); |
| 347 } | 367 } |
| 348 } | 368 } |
| 349 | 369 |
| 350 void TileManager::renderingStats(RenderingStats* stats) { | 370 void TileManager::GetRenderingStats(RenderingStats* stats) { |
| 351 stats->totalRasterizeTimeInSeconds = | 371 stats->totalRasterizeTimeInSeconds = |
| 352 rendering_stats_.totalRasterizeTimeInSeconds; | 372 rendering_stats_.totalRasterizeTimeInSeconds; |
| 353 stats->totalPixelsRasterized = rendering_stats_.totalPixelsRasterized; | 373 stats->totalPixelsRasterized = rendering_stats_.totalPixelsRasterized; |
| 354 stats->totalDeferredImageDecodeCount = | 374 stats->totalDeferredImageDecodeCount = |
| 355 rendering_stats_.totalDeferredImageDecodeCount; | 375 rendering_stats_.totalDeferredImageDecodeCount; |
| 356 stats->totalDeferredImageCacheHitCount = | 376 stats->totalDeferredImageCacheHitCount = |
| 357 rendering_stats_.totalDeferredImageCacheHitCount; | 377 rendering_stats_.totalDeferredImageCacheHitCount; |
| 358 stats->totalImageGatheringCount = rendering_stats_.totalImageGatheringCount; | 378 stats->totalImageGatheringCount = rendering_stats_.totalImageGatheringCount; |
| 359 stats->totalDeferredImageDecodeTimeInSeconds = | 379 stats->totalDeferredImageDecodeTimeInSeconds = |
| 360 rendering_stats_.totalDeferredImageDecodeTimeInSeconds; | 380 rendering_stats_.totalDeferredImageDecodeTimeInSeconds; |
| 361 stats->totalImageGatheringTimeInSeconds = | 381 stats->totalImageGatheringTimeInSeconds = |
| 362 rendering_stats_.totalImageGatheringTimeInSeconds; | 382 rendering_stats_.totalImageGatheringTimeInSeconds; |
| 363 } | 383 } |
| 364 | 384 |
| 385 int TileManager::GetTilesInBinCount(TileManagerBin bin, WhichTree tree) { |
| 386 DCHECK(bin >= 0); |
| 387 DCHECK(bin < NUM_BINS); |
| 388 DCHECK(tree >= 0); |
| 389 DCHECK(tree < NUM_TREES); |
| 390 return tiles_in_bin_count_[bin][tree]; |
| 391 } |
| 392 |
| 393 int TileManager::GetDrawableTilesInBinCount( |
| 394 TileManagerBin bin, WhichTree tree) { |
| 395 DCHECK(bin >= 0); |
| 396 DCHECK(bin < NUM_BINS); |
| 397 DCHECK(tree >= 0); |
| 398 DCHECK(tree < NUM_TREES); |
| 399 return drawable_tiles_in_bin_count_[bin][tree]; |
| 400 } |
| 401 |
| 402 void TileManager::ResetBinCounts() { |
| 403 for (int i = 0; i < NUM_BINS; ++i) |
| 404 for (int j = 0; j < NUM_TREES; ++j) |
| 405 tiles_in_bin_count_[i][j] = drawable_tiles_in_bin_count_[i][j] = 0; |
| 406 } |
| 407 |
| 365 void TileManager::AssignGpuMemoryToTiles() { | 408 void TileManager::AssignGpuMemoryToTiles() { |
| 366 TRACE_EVENT0("cc", "TileManager::AssignGpuMemoryToTiles"); | 409 TRACE_EVENT0("cc", "TileManager::AssignGpuMemoryToTiles"); |
| 367 // Some memory cannot be released. Figure out which. | 410 // Some memory cannot be released. Figure out which. |
| 368 size_t unreleasable_bytes = 0; | 411 size_t unreleasable_bytes = 0; |
| 369 for (TileVector::iterator it = tiles_.begin(); it != tiles_.end(); ++it) { | 412 for (TileVector::iterator it = tiles_.begin(); it != tiles_.end(); ++it) { |
| 370 Tile* tile = *it; | 413 Tile* tile = *it; |
| 371 if (!tile->managed_state().can_be_freed) | 414 if (!tile->managed_state().can_be_freed) |
| 372 unreleasable_bytes += tile->bytes_consumed_if_allocated(); | 415 unreleasable_bytes += tile->bytes_consumed_if_allocated(); |
| 373 } | 416 } |
| 374 | 417 |
| 375 // Now give memory out to the tiles until we're out, and build | 418 // Now give memory out to the tiles until we're out, and build |
| 376 // the needs-to-be-rasterized queue. | 419 // the needs-to-be-rasterized queue. |
| 377 tiles_that_need_to_be_rasterized_.erase( | 420 tiles_that_need_to_be_rasterized_.erase( |
| 378 tiles_that_need_to_be_rasterized_.begin(), | 421 tiles_that_need_to_be_rasterized_.begin(), |
| 379 tiles_that_need_to_be_rasterized_.end()); | 422 tiles_that_need_to_be_rasterized_.end()); |
| 380 | 423 |
| 381 // Reset the image decoding list so that we don't mess up with tile | 424 // Reset the image decoding list so that we don't mess up with tile |
| 382 // priorities. Tiles will be added to the image decoding list again | 425 // priorities. Tiles will be added to the image decoding list again |
| 383 // when DispatchMoreTasks() is called. | 426 // when DispatchMoreTasks() is called. |
| 384 tiles_with_image_decoding_tasks_.clear(); | 427 tiles_with_image_decoding_tasks_.clear(); |
| 385 | 428 |
| 386 size_t bytes_left = global_state_.memory_limit_in_bytes - unreleasable_bytes; | 429 size_t bytes_left = global_state_.memory_limit_in_bytes - unreleasable_bytes; |
| 387 for (TileVector::iterator it = tiles_.begin(); it != tiles_.end(); ++it) { | 430 for (TileVector::iterator it = tiles_.begin(); it != tiles_.end(); ++it) { |
| 388 Tile* tile = *it; | 431 Tile* tile = *it; |
| 389 size_t tile_bytes = tile->bytes_consumed_if_allocated(); | 432 size_t tile_bytes = tile->bytes_consumed_if_allocated(); |
| 390 ManagedTileState& managed_tile_state = tile->managed_state(); | 433 ManagedTileState& managed_tile_state = tile->managed_state(); |
| 391 if (!managed_tile_state.can_be_freed) | 434 if (!managed_tile_state.can_be_freed) |
| 392 continue; | 435 continue; |
| 393 if (managed_tile_state.bin == NEVER_BIN) { | 436 if (managed_tile_state.raster_bin == NEVER_BIN) { |
| 394 managed_tile_state.can_use_gpu_memory = false; | 437 managed_tile_state.can_use_gpu_memory = false; |
| 395 FreeResourcesForTile(tile); | 438 FreeResourcesForTile(tile); |
| 396 continue; | 439 continue; |
| 397 } | 440 } |
| 398 if (tile_bytes > bytes_left) { | 441 if (tile_bytes > bytes_left) { |
| 399 managed_tile_state.can_use_gpu_memory = false; | 442 managed_tile_state.can_use_gpu_memory = false; |
| 400 FreeResourcesForTile(tile); | 443 FreeResourcesForTile(tile); |
| 401 continue; | 444 continue; |
| 402 } | 445 } |
| 403 bytes_left -= tile_bytes; | 446 bytes_left -= tile_bytes; |
| (...skipping 233 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 637 managed_tile_state.resource_is_being_initialized = false; | 680 managed_tile_state.resource_is_being_initialized = false; |
| 638 } | 681 } |
| 639 DispatchMoreTasks(); | 682 DispatchMoreTasks(); |
| 640 } | 683 } |
| 641 | 684 |
| 642 void TileManager::DidFinishTileInitialization(Tile* tile) { | 685 void TileManager::DidFinishTileInitialization(Tile* tile) { |
| 643 ManagedTileState& managed_tile_state = tile->managed_state(); | 686 ManagedTileState& managed_tile_state = tile->managed_state(); |
| 644 DCHECK(managed_tile_state.resource); | 687 DCHECK(managed_tile_state.resource); |
| 645 managed_tile_state.resource_is_being_initialized = false; | 688 managed_tile_state.resource_is_being_initialized = false; |
| 646 managed_tile_state.can_be_freed = true; | 689 managed_tile_state.can_be_freed = true; |
| 690 for (int i = 0; i < NUM_TREES; ++i) |
| 691 drawable_tiles_in_bin_count_[managed_tile_state.bin[i]][i]++; |
| 647 } | 692 } |
| 648 | 693 |
| 649 } | 694 } |
| OLD | NEW |