Chromium Code Reviews| 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" |
| (...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 59 from_here, | 59 from_here, |
| 60 base::Bind(&RunRasterTask, | 60 base::Bind(&RunRasterTask, |
| 61 base::Unretained(picture_pile), | 61 base::Unretained(picture_pile), |
| 62 mapped_buffer, | 62 mapped_buffer, |
| 63 rect, | 63 rect, |
| 64 contents_scale, | 64 contents_scale, |
| 65 stats), | 65 stats), |
| 66 base::Bind(&RasterThread::RunReply, base::Unretained(this), reply)); | 66 base::Bind(&RasterThread::RunReply, base::Unretained(this), reply)); |
| 67 } | 67 } |
| 68 | 68 |
| 69 void PostImageDecodingTaskAndReply(const tracked_objects::Location& from_here, | |
| 70 skia::LazyPixelRef* pixel_ref, | |
| 71 const base::Closure& reply) { | |
| 72 ++num_pending_tasks_; | |
| 73 message_loop_proxy()->PostTaskAndReply( | |
| 74 from_here, | |
| 75 base::Bind(&skia::LazyPixelRef::Decode, base::Unretained(pixel_ref)), | |
| 76 base::Bind(&RasterThread::RunReply, base::Unretained(this), reply)); | |
| 77 } | |
| 78 | |
| 69 private: | 79 private: |
| 70 static void RunRasterTask(PicturePileImpl* picture_pile, | 80 static void RunRasterTask(PicturePileImpl* picture_pile, |
| 71 uint8_t* mapped_buffer, | 81 uint8_t* mapped_buffer, |
| 72 const gfx::Rect& rect, | 82 const gfx::Rect& rect, |
| 73 float contents_scale, | 83 float contents_scale, |
| 74 RenderingStats* stats) { | 84 RenderingStats* stats) { |
| 75 TRACE_EVENT0("cc", "RasterThread::RunRasterTask"); | 85 TRACE_EVENT0("cc", "RasterThread::RunRasterTask"); |
| 76 DCHECK(picture_pile); | 86 DCHECK(picture_pile); |
| 77 DCHECK(mapped_buffer); | 87 DCHECK(mapped_buffer); |
| 78 SkBitmap bitmap; | 88 SkBitmap bitmap; |
| (...skipping 160 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 239 mts.bin = NOW_BIN; | 249 mts.bin = NOW_BIN; |
| 240 continue; | 250 continue; |
| 241 } | 251 } |
| 242 | 252 |
| 243 if (prio.time_to_needed_in_seconds() < prepainting_window_time_seconds) { | 253 if (prio.time_to_needed_in_seconds() < prepainting_window_time_seconds) { |
| 244 mts.bin = SOON_BIN; | 254 mts.bin = SOON_BIN; |
| 245 continue; | 255 continue; |
| 246 } | 256 } |
| 247 | 257 |
| 248 mts.bin = EVENTUALLY_BIN; | 258 mts.bin = EVENTUALLY_BIN; |
| 259 | |
| 260 // Update all the SkPixelRefs this tile intersects. | |
| 261 mts.pending_pixel_refs.clear(); | |
| 262 mts.has_image_decoding_info = false; | |
|
reveman
2012/12/11 01:35:42
Why do you clear this here? Shouldn't we just init
qinmin
2012/12/11 04:30:15
moved it to the ctor
On 2012/12/11 01:35:42, David
| |
| 249 } | 263 } |
| 250 | 264 |
| 251 // Memory limit policy works by mapping some bin states to the NEVER bin. | 265 // Memory limit policy works by mapping some bin states to the NEVER bin. |
| 252 TileManagerBin bin_map[NUM_BINS]; | 266 TileManagerBin bin_map[NUM_BINS]; |
| 253 if (global_state_.memory_limit_policy == ALLOW_NOTHING) { | 267 if (global_state_.memory_limit_policy == ALLOW_NOTHING) { |
| 254 bin_map[NOW_BIN] = NEVER_BIN; | 268 bin_map[NOW_BIN] = NEVER_BIN; |
| 255 bin_map[SOON_BIN] = NEVER_BIN; | 269 bin_map[SOON_BIN] = NEVER_BIN; |
| 256 bin_map[EVENTUALLY_BIN] = NEVER_BIN; | 270 bin_map[EVENTUALLY_BIN] = NEVER_BIN; |
| 257 bin_map[NEVER_BIN] = NEVER_BIN; | 271 bin_map[NEVER_BIN] = NEVER_BIN; |
| 258 } else if (global_state_.memory_limit_policy == ALLOW_ABSOLUTE_MINIMUM) { | 272 } else if (global_state_.memory_limit_policy == ALLOW_ABSOLUTE_MINIMUM) { |
| (...skipping 18 matching lines...) Expand all Loading... | |
| 277 tile->managed_state().bin = bin; | 291 tile->managed_state().bin = bin; |
| 278 } | 292 } |
| 279 | 293 |
| 280 // Sort by bin. | 294 // Sort by bin. |
| 281 std::sort(tiles_.begin(), tiles_.end(), BinComparator()); | 295 std::sort(tiles_.begin(), tiles_.end(), BinComparator()); |
| 282 | 296 |
| 283 // Assign gpu memory and determine what tiles need to be rasterized. | 297 // Assign gpu memory and determine what tiles need to be rasterized. |
| 284 AssignGpuMemoryToTiles(); | 298 AssignGpuMemoryToTiles(); |
| 285 | 299 |
| 286 // Finally, kick the rasterizer. | 300 // Finally, kick the rasterizer. |
| 287 DispatchMoreRasterTasks(); | 301 DispatchMoreTasks(); |
| 288 } | 302 } |
| 289 | 303 |
| 290 void TileManager::CheckForCompletedSetPixels() { | 304 void TileManager::CheckForCompletedSetPixels() { |
| 291 check_for_completed_set_pixels_pending_ = false; | 305 check_for_completed_set_pixels_pending_ = false; |
| 292 | 306 |
| 293 while (!tiles_with_pending_set_pixels_.empty()) { | 307 while (!tiles_with_pending_set_pixels_.empty()) { |
| 294 Tile* tile = tiles_with_pending_set_pixels_.front(); | 308 Tile* tile = tiles_with_pending_set_pixels_.front(); |
| 295 DCHECK(tile->managed_state().resource); | 309 DCHECK(tile->managed_state().resource); |
| 296 | 310 |
| 297 // Set pixel tasks complete in the order they are posted. | 311 // Set pixel tasks complete in the order they are posted. |
| (...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 356 tiles_that_need_to_be_rasterized_.push_back(tile); | 370 tiles_that_need_to_be_rasterized_.push_back(tile); |
| 357 } | 371 } |
| 358 | 372 |
| 359 // Reverse two tiles_that_need_* vectors such that pop_back gets | 373 // Reverse two tiles_that_need_* vectors such that pop_back gets |
| 360 // the highest priority tile. | 374 // the highest priority tile. |
| 361 std::reverse( | 375 std::reverse( |
| 362 tiles_that_need_to_be_rasterized_.begin(), | 376 tiles_that_need_to_be_rasterized_.begin(), |
| 363 tiles_that_need_to_be_rasterized_.end()); | 377 tiles_that_need_to_be_rasterized_.end()); |
| 364 } | 378 } |
| 365 | 379 |
| 380 void TileManager::GetImageInformationForTile(Tile* tile) { | |
|
reveman
2012/12/11 01:35:42
I don't think having this in a separate function i
qinmin
2012/12/11 04:30:15
Done.
| |
| 381 ManagedTileState& managed_state = tile->managed_state(); | |
| 382 if (!managed_state.has_image_decoding_info) { | |
| 383 const_cast<PicturePileImpl *>(tile->picture_pile())->GatherPixelRefs( | |
| 384 tile->content_rect_, managed_state.pending_pixel_refs); | |
| 385 managed_state.has_image_decoding_info = true; | |
| 386 } | |
| 387 } | |
| 388 | |
| 366 void TileManager::FreeResourcesForTile(Tile* tile) { | 389 void TileManager::FreeResourcesForTile(Tile* tile) { |
| 367 ManagedTileState& managed_tile_state = tile->managed_state(); | 390 ManagedTileState& managed_tile_state = tile->managed_state(); |
| 368 DCHECK(managed_tile_state.can_be_freed); | 391 DCHECK(managed_tile_state.can_be_freed); |
| 369 if (managed_tile_state.resource) | 392 if (managed_tile_state.resource) |
| 370 resource_pool_->ReleaseResource(managed_tile_state.resource.Pass()); | 393 resource_pool_->ReleaseResource(managed_tile_state.resource.Pass()); |
| 371 } | 394 } |
| 372 | 395 |
| 373 void TileManager::DispatchMoreRasterTasks() { | 396 RasterThread* TileManager::GetFreeRasterThread() { |
| 397 RasterThread* thread = 0; | |
| 398 for (RasterThreadVector::iterator it = raster_threads_.begin(); | |
| 399 it != raster_threads_.end(); ++it) { | |
| 400 if ((*it)->num_pending_tasks() == kNumPendingRasterTasksPerThread) | |
| 401 continue; | |
| 402 // Check if this is the best thread we've found so far. | |
| 403 if (!thread || (*it)->num_pending_tasks() < thread->num_pending_tasks()) | |
| 404 thread = *it; | |
| 405 } | |
| 406 return thread; | |
| 407 } | |
| 408 | |
| 409 void TileManager::DispatchMoreTasks() { | |
| 410 // Because tiles in the image decoding list have higher priorities, we | |
| 411 // need to process those tiles first before we start to handle the tiles | |
| 412 // in the need_to_be_rasterized queue. | |
| 413 for (TileList::iterator it = tiles_have_image_decoding_tasks_.begin(); | |
| 414 it != tiles_have_image_decoding_tasks_.end(); ++it) { | |
| 415 if (!HasImageDecodingTasks(*it)) { | |
| 416 RasterThread* thread = GetFreeRasterThread(); | |
| 417 if (!thread) | |
| 418 return; | |
| 419 DispatchOneRasterTask(thread, *it); | |
| 420 tiles_have_image_decoding_tasks_.erase(it); | |
|
reveman
2012/12/11 01:35:42
do you need a temporary "to be removed" list here?
qinmin
2012/12/11 04:30:15
Changed the code to erase(it++).
On 2012/12/11 01
| |
| 421 } | |
| 422 } | |
| 423 | |
| 424 // Process all tiles in the need_to_be_rasterized queue. If a tile has | |
| 425 // image decoding tasks, put it to the back of the image decoding list. | |
| 374 while (!tiles_that_need_to_be_rasterized_.empty()) { | 426 while (!tiles_that_need_to_be_rasterized_.empty()) { |
| 375 RasterThread* thread = 0; | 427 RasterThread* thread = GetFreeRasterThread(); |
| 376 | |
| 377 for (RasterThreadVector::iterator it = raster_threads_.begin(); | |
| 378 it != raster_threads_.end(); ++it) { | |
| 379 if ((*it)->num_pending_tasks() == kNumPendingRasterTasksPerThread) | |
| 380 continue; | |
| 381 // Check if this is the best thread we've found so far. | |
| 382 if (!thread || (*it)->num_pending_tasks() < thread->num_pending_tasks()) | |
| 383 thread = *it; | |
| 384 } | |
| 385 | |
| 386 // Stop dispatching tasks when all threads are busy. | |
| 387 if (!thread) | 428 if (!thread) |
| 388 return; | 429 return; |
| 389 | 430 |
| 390 DispatchOneRasterTask(thread, tiles_that_need_to_be_rasterized_.back()); | 431 Tile* tile = tiles_that_need_to_be_rasterized_.back(); |
| 432 if (HasImageDecodingTasks(tile)) | |
| 433 tiles_have_image_decoding_tasks_.push_back(tile); | |
| 434 else | |
| 435 DispatchOneRasterTask(thread, tile); | |
|
reveman
2012/12/11 01:35:42
hm, thread might not be the correct thread to disp
qinmin
2012/12/11 04:30:15
You are right, somehow i missed that when rewritin
| |
| 391 tiles_that_need_to_be_rasterized_.pop_back(); | 436 tiles_that_need_to_be_rasterized_.pop_back(); |
| 392 } | 437 } |
| 393 } | 438 } |
| 394 | 439 |
| 440 bool TileManager::HasImageDecodingTasks(Tile* tile) { | |
|
reveman
2012/12/11 01:35:42
Can you change this to something like:
void Dispat
qinmin
2012/12/11 04:30:15
Done.
On 2012/12/11 01:35:42, David Reveman wrote
| |
| 441 if (!tile->managed_state().has_image_decoding_info) | |
| 442 GetImageInformationForTile(tile); | |
| 443 | |
| 444 RasterThread* thread = 0; | |
| 445 std::list<skia::LazyPixelRef*>& pending_pixel_refs = | |
| 446 tile->managed_state().pending_pixel_refs; | |
| 447 for (std::list<skia::LazyPixelRef*>::iterator it = pending_pixel_refs.begin(); | |
| 448 it != pending_pixel_refs.end(); ++it) { | |
| 449 if (pending_decode_tasks_.end() != pending_decode_tasks_.find( | |
| 450 (*it)->getGenerationID())) | |
| 451 continue; | |
| 452 if ((*it)->PrepareToDecode(skia::LazyPixelRef::PrepareParams())) { | |
| 453 pending_pixel_refs.erase(it); | |
| 454 } else { | |
| 455 thread = GetFreeRasterThread(); | |
| 456 if (thread) | |
| 457 DispatchOneImageDecodingTask(thread, tile, *it); | |
| 458 } | |
| 459 } | |
| 460 | |
| 461 return !pending_pixel_refs.empty(); | |
| 462 } | |
| 463 | |
| 464 void TileManager::DispatchOneImageDecodingTask(RasterThread* thread, | |
| 465 scoped_refptr<Tile> tile, | |
| 466 skia::LazyPixelRef* pixel_ref) { | |
| 467 TRACE_EVENT0("cc", "TileManager::DispatchOneImageDecodingTask"); | |
| 468 uint32_t pixel_ref_id = pixel_ref->getGenerationID(); | |
| 469 DCHECK(pending_decode_tasks_.end() == | |
| 470 pending_decode_tasks_.find(pixel_ref_id)); | |
| 471 pending_decode_tasks_[pixel_ref_id] = pixel_ref; | |
| 472 | |
| 473 thread->PostImageDecodingTaskAndReply( | |
| 474 FROM_HERE, | |
| 475 pixel_ref, | |
| 476 base::Bind(&TileManager::OnImageDecodingTaskCompleted, | |
| 477 base::Unretained(this), | |
| 478 tile, | |
| 479 pixel_ref_id)); | |
| 480 } | |
| 481 | |
| 482 void TileManager::OnImageDecodingTaskCompleted(scoped_refptr<Tile> tile, | |
| 483 uint32_t pixel_ref_id) { | |
| 484 TRACE_EVENT0("cc", "TileManager::OnImageDecoded"); | |
| 485 pending_decode_tasks_.erase(pixel_ref_id); | |
| 486 | |
| 487 for (TileList::iterator it = tiles_have_image_decoding_tasks_.begin(); | |
| 488 it != tiles_have_image_decoding_tasks_.end(); ++it) { | |
| 489 std::list<skia::LazyPixelRef*>& pixel_refs = | |
| 490 (*it)->managed_state().pending_pixel_refs; | |
| 491 for (std::list<skia::LazyPixelRef*>::iterator pixel_it = | |
| 492 pixel_refs.begin(); pixel_it != pixel_refs.end(); ++pixel_it) { | |
| 493 if (pixel_ref_id == (*pixel_it)->getGenerationID()) { | |
| 494 pixel_refs.erase(pixel_it); | |
| 495 break; | |
| 496 } | |
| 497 } | |
| 498 } | |
| 499 | |
| 500 DispatchMoreTasks(); | |
| 501 } | |
| 502 | |
| 395 void TileManager::DispatchOneRasterTask( | 503 void TileManager::DispatchOneRasterTask( |
| 396 RasterThread* thread, scoped_refptr<Tile> tile) { | 504 RasterThread* thread, scoped_refptr<Tile> tile) { |
| 397 TRACE_EVENT0("cc", "TileManager::DispatchOneRasterTask"); | 505 TRACE_EVENT0("cc", "TileManager::DispatchOneRasterTask"); |
| 398 ManagedTileState& managed_tile_state = tile->managed_state(); | 506 ManagedTileState& managed_tile_state = tile->managed_state(); |
| 399 DCHECK(managed_tile_state.can_use_gpu_memory); | 507 DCHECK(managed_tile_state.can_use_gpu_memory); |
| 400 scoped_ptr<ResourcePool::Resource> resource = | 508 scoped_ptr<ResourcePool::Resource> resource = |
| 401 resource_pool_->AcquireResource(tile->tile_size_.size(), tile->format_); | 509 resource_pool_->AcquireResource(tile->tile_size_.size(), tile->format_); |
| 402 resource_pool_->resource_provider()->acquirePixelBuffer(resource->id()); | 510 resource_pool_->resource_provider()->acquirePixelBuffer(resource->id()); |
| 403 | 511 |
| 404 managed_tile_state.resource_is_being_initialized = true; | 512 managed_tile_state.resource_is_being_initialized = true; |
| (...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 439 resource_pool_->resource_provider()->unmapPixelBuffer(resource->id()); | 547 resource_pool_->resource_provider()->unmapPixelBuffer(resource->id()); |
| 440 | 548 |
| 441 ManagedTileState& managed_tile_state = tile->managed_state(); | 549 ManagedTileState& managed_tile_state = tile->managed_state(); |
| 442 managed_tile_state.can_be_freed = true; | 550 managed_tile_state.can_be_freed = true; |
| 443 | 551 |
| 444 // Tile can be freed after the completion of the raster task. Call | 552 // Tile can be freed after the completion of the raster task. Call |
| 445 // AssignGpuMemoryToTiles() to re-assign gpu memory to highest priority | 553 // AssignGpuMemoryToTiles() to re-assign gpu memory to highest priority |
| 446 // tiles. The result of this could be that this tile is no longer | 554 // tiles. The result of this could be that this tile is no longer |
| 447 // allowed to use gpu memory and in that case we need to abort | 555 // allowed to use gpu memory and in that case we need to abort |
| 448 // initialization and free all associated resources before calling | 556 // initialization and free all associated resources before calling |
| 449 // DispatchMoreRasterTasks(). | 557 // DispatchMoreTasks(). |
| 450 AssignGpuMemoryToTiles(); | 558 AssignGpuMemoryToTiles(); |
| 451 | 559 |
| 452 // Finish resource initialization if |can_use_gpu_memory| is true. | 560 // Finish resource initialization if |can_use_gpu_memory| is true. |
| 453 if (managed_tile_state.can_use_gpu_memory) { | 561 if (managed_tile_state.can_use_gpu_memory) { |
| 454 // The component order may be bgra if we're uploading bgra pixels to rgba | 562 // The component order may be bgra if we're uploading bgra pixels to rgba |
| 455 // texture. Mark contents as swizzled if image component order is | 563 // texture. Mark contents as swizzled if image component order is |
| 456 // different than texture format. | 564 // different than texture format. |
| 457 managed_tile_state.contents_swizzled = | 565 managed_tile_state.contents_swizzled = |
| 458 !PlatformColor::sameComponentOrder(tile->format_); | 566 !PlatformColor::sameComponentOrder(tile->format_); |
| 459 | 567 |
| 460 // Tile resources can't be freed until upload has completed. | 568 // Tile resources can't be freed until upload has completed. |
| 461 managed_tile_state.can_be_freed = false; | 569 managed_tile_state.can_be_freed = false; |
| 462 | 570 |
| 463 resource_pool_->resource_provider()->beginSetPixels(resource->id()); | 571 resource_pool_->resource_provider()->beginSetPixels(resource->id()); |
| 464 managed_tile_state.resource = resource.Pass(); | 572 managed_tile_state.resource = resource.Pass(); |
| 465 tiles_with_pending_set_pixels_.push(tile); | 573 tiles_with_pending_set_pixels_.push(tile); |
| 466 | 574 |
| 467 ScheduleCheckForCompletedSetPixels(); | 575 ScheduleCheckForCompletedSetPixels(); |
| 468 } else { | 576 } else { |
| 469 resource_pool_->resource_provider()->releasePixelBuffer(resource->id()); | 577 resource_pool_->resource_provider()->releasePixelBuffer(resource->id()); |
| 470 resource_pool_->ReleaseResource(resource.Pass()); | 578 resource_pool_->ReleaseResource(resource.Pass()); |
| 471 managed_tile_state.resource_is_being_initialized = false; | 579 managed_tile_state.resource_is_being_initialized = false; |
| 472 } | 580 } |
| 473 | 581 |
| 474 DispatchMoreRasterTasks(); | 582 DispatchMoreTasks(); |
| 475 } | 583 } |
| 476 | 584 |
| 477 void TileManager::DidFinishTileInitialization(Tile* tile) { | 585 void TileManager::DidFinishTileInitialization(Tile* tile) { |
| 478 ManagedTileState& managed_tile_state = tile->managed_state(); | 586 ManagedTileState& managed_tile_state = tile->managed_state(); |
| 479 DCHECK(managed_tile_state.resource); | 587 DCHECK(managed_tile_state.resource); |
| 480 managed_tile_state.resource_is_being_initialized = false; | 588 managed_tile_state.resource_is_being_initialized = false; |
| 481 managed_tile_state.can_be_freed = true; | 589 managed_tile_state.can_be_freed = true; |
| 482 } | 590 } |
| 483 | 591 |
| 484 } | 592 } |
| OLD | NEW |