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 15 matching lines...) Expand all Loading... | |
94 | 104 |
95 int num_pending_tasks_; | 105 int num_pending_tasks_; |
96 | 106 |
97 DISALLOW_COPY_AND_ASSIGN(RasterThread); | 107 DISALLOW_COPY_AND_ASSIGN(RasterThread); |
98 }; | 108 }; |
99 | 109 |
100 ManagedTileState::ManagedTileState() | 110 ManagedTileState::ManagedTileState() |
101 : can_use_gpu_memory(false), | 111 : can_use_gpu_memory(false), |
102 can_be_freed(true), | 112 can_be_freed(true), |
103 resource_is_being_initialized(false), | 113 resource_is_being_initialized(false), |
104 contents_swizzled(false) { | 114 contents_swizzled(false), |
115 need_to_gather_pixel_refs(true) { | |
105 } | 116 } |
106 | 117 |
107 ManagedTileState::~ManagedTileState() { | 118 ManagedTileState::~ManagedTileState() { |
108 DCHECK(!resource); | 119 DCHECK(!resource); |
109 DCHECK(!resource_is_being_initialized); | 120 DCHECK(!resource_is_being_initialized); |
110 } | 121 } |
111 | 122 |
112 TileManager::TileManager( | 123 TileManager::TileManager( |
113 TileManagerClient* client, | 124 TileManagerClient* client, |
114 ResourceProvider* resource_provider, | 125 ResourceProvider* resource_provider, |
(...skipping 162 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
277 tile->managed_state().bin = bin; | 288 tile->managed_state().bin = bin; |
278 } | 289 } |
279 | 290 |
280 // Sort by bin. | 291 // Sort by bin. |
281 std::sort(tiles_.begin(), tiles_.end(), BinComparator()); | 292 std::sort(tiles_.begin(), tiles_.end(), BinComparator()); |
282 | 293 |
283 // Assign gpu memory and determine what tiles need to be rasterized. | 294 // Assign gpu memory and determine what tiles need to be rasterized. |
284 AssignGpuMemoryToTiles(); | 295 AssignGpuMemoryToTiles(); |
285 | 296 |
286 // Finally, kick the rasterizer. | 297 // Finally, kick the rasterizer. |
287 DispatchMoreRasterTasks(); | 298 DispatchMoreTasks(); |
288 } | 299 } |
289 | 300 |
290 void TileManager::CheckForCompletedSetPixels() { | 301 void TileManager::CheckForCompletedSetPixels() { |
291 check_for_completed_set_pixels_pending_ = false; | 302 check_for_completed_set_pixels_pending_ = false; |
292 | 303 |
293 while (!tiles_with_pending_set_pixels_.empty()) { | 304 while (!tiles_with_pending_set_pixels_.empty()) { |
294 Tile* tile = tiles_with_pending_set_pixels_.front(); | 305 Tile* tile = tiles_with_pending_set_pixels_.front(); |
295 DCHECK(tile->managed_state().resource); | 306 DCHECK(tile->managed_state().resource); |
296 | 307 |
297 // Set pixel tasks complete in the order they are posted. | 308 // Set pixel tasks complete in the order they are posted. |
(...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
363 tiles_that_need_to_be_rasterized_.end()); | 374 tiles_that_need_to_be_rasterized_.end()); |
364 } | 375 } |
365 | 376 |
366 void TileManager::FreeResourcesForTile(Tile* tile) { | 377 void TileManager::FreeResourcesForTile(Tile* tile) { |
367 ManagedTileState& managed_tile_state = tile->managed_state(); | 378 ManagedTileState& managed_tile_state = tile->managed_state(); |
368 DCHECK(managed_tile_state.can_be_freed); | 379 DCHECK(managed_tile_state.can_be_freed); |
369 if (managed_tile_state.resource) | 380 if (managed_tile_state.resource) |
370 resource_pool_->ReleaseResource(managed_tile_state.resource.Pass()); | 381 resource_pool_->ReleaseResource(managed_tile_state.resource.Pass()); |
371 } | 382 } |
372 | 383 |
373 void TileManager::DispatchMoreRasterTasks() { | 384 RasterThread* TileManager::GetFreeRasterThread() { |
385 RasterThread* thread = 0; | |
386 for (RasterThreadVector::iterator it = raster_threads_.begin(); | |
387 it != raster_threads_.end(); ++it) { | |
388 if ((*it)->num_pending_tasks() == kNumPendingRasterTasksPerThread) | |
389 continue; | |
390 // Check if this is the best thread we've found so far. | |
391 if (!thread || (*it)->num_pending_tasks() < thread->num_pending_tasks()) | |
392 thread = *it; | |
393 } | |
394 return thread; | |
395 } | |
396 | |
397 void TileManager::DispatchMoreTasks() { | |
398 // Because tiles in the image decoding list have higher priorities, we | |
399 // need to process those tiles first before we start to handle the tiles | |
400 // in the need_to_be_rasterized queue. | |
401 std::list<Tile*>::iterator it = tiles_with_image_decoding_tasks_.begin(); | |
402 while (it != tiles_with_image_decoding_tasks_.end()) { | |
403 DispatchImageDecodingTasksForTile(*it); | |
404 ManagedTileState& managed_state = (*it)->managed_state(); | |
405 if (managed_state.pending_pixel_refs.empty()) { | |
406 RasterThread* thread = GetFreeRasterThread(); | |
407 if (!thread) | |
408 return; | |
409 DispatchOneRasterTask(thread, *it); | |
410 tiles_with_image_decoding_tasks_.erase(it++); | |
411 } else { | |
412 ++it; | |
413 } | |
414 } | |
415 | |
416 // Process all tiles in the need_to_be_rasterized queue. If a tile has | |
417 // image decoding tasks, put it to the back of the image decoding list. | |
374 while (!tiles_that_need_to_be_rasterized_.empty()) { | 418 while (!tiles_that_need_to_be_rasterized_.empty()) { |
375 RasterThread* thread = 0; | 419 Tile* tile = tiles_that_need_to_be_rasterized_.back(); |
376 | 420 DispatchImageDecodingTasksForTile(tile); |
377 for (RasterThreadVector::iterator it = raster_threads_.begin(); | 421 ManagedTileState& managed_state = tile->managed_state(); |
378 it != raster_threads_.end(); ++it) { | 422 if (!managed_state.pending_pixel_refs.empty()) |
379 if ((*it)->num_pending_tasks() == kNumPendingRasterTasksPerThread) | 423 tiles_with_image_decoding_tasks_.push_back(tile); |
380 continue; | 424 else { |
reveman
2012/12/11 05:07:18
nit: curly braces around both IF and ELSE required
qinmin
2012/12/11 05:36:20
Done.
| |
381 // Check if this is the best thread we've found so far. | 425 RasterThread* thread = GetFreeRasterThread(); |
382 if (!thread || (*it)->num_pending_tasks() < thread->num_pending_tasks()) | 426 if (!thread) |
383 thread = *it; | 427 return; |
428 DispatchOneRasterTask(thread, tile); | |
384 } | 429 } |
385 | |
386 // Stop dispatching tasks when all threads are busy. | |
387 if (!thread) | |
388 return; | |
389 | |
390 DispatchOneRasterTask(thread, tiles_that_need_to_be_rasterized_.back()); | |
391 tiles_that_need_to_be_rasterized_.pop_back(); | 430 tiles_that_need_to_be_rasterized_.pop_back(); |
392 } | 431 } |
393 } | 432 } |
394 | 433 |
434 void TileManager::DispatchImageDecodingTasksForTile(Tile* tile) { | |
435 ManagedTileState& managed_state = tile->managed_state(); | |
436 if (!managed_state.need_to_gather_pixel_refs) { | |
437 const_cast<PicturePileImpl *>(tile->picture_pile())->GatherPixelRefs( | |
438 tile->content_rect_, managed_state.pending_pixel_refs); | |
439 managed_state.need_to_gather_pixel_refs = false; | |
440 } | |
441 | |
442 RasterThread* thread = 0; | |
reveman
2012/12/11 05:07:18
nit: |thread| is not needed in this scope. please
qinmin
2012/12/11 05:36:20
Done.
| |
443 std::list<skia::LazyPixelRef*>& pending_pixel_refs = | |
444 tile->managed_state().pending_pixel_refs; | |
445 std::list<skia::LazyPixelRef*>::iterator it = pending_pixel_refs.begin(); | |
446 while (it != pending_pixel_refs.end()) { | |
447 if (pending_decode_tasks_.end() != pending_decode_tasks_.find( | |
448 (*it)->getGenerationID())) { | |
449 ++it; | |
450 continue; | |
451 } | |
452 if ((*it)->PrepareToDecode(skia::LazyPixelRef::PrepareParams())) | |
453 pending_pixel_refs.erase(it++); | |
454 else { | |
reveman
2012/12/11 05:07:18
nit: curly braces around both IF and ELSE required
qinmin
2012/12/11 05:36:20
Done.
| |
455 thread = GetFreeRasterThread(); | |
456 if (thread) | |
457 DispatchOneImageDecodingTask(thread, tile, *it); | |
458 ++it; | |
459 } | |
460 } | |
461 } | |
462 | |
463 void TileManager::DispatchOneImageDecodingTask(RasterThread* thread, | |
464 scoped_refptr<Tile> tile, | |
465 skia::LazyPixelRef* pixel_ref) { | |
466 TRACE_EVENT0("cc", "TileManager::DispatchOneImageDecodingTask"); | |
467 uint32_t pixel_ref_id = pixel_ref->getGenerationID(); | |
468 DCHECK(pending_decode_tasks_.end() == | |
469 pending_decode_tasks_.find(pixel_ref_id)); | |
470 pending_decode_tasks_[pixel_ref_id] = pixel_ref; | |
471 | |
472 thread->PostImageDecodingTaskAndReply( | |
473 FROM_HERE, | |
474 pixel_ref, | |
475 base::Bind(&TileManager::OnImageDecodingTaskCompleted, | |
476 base::Unretained(this), | |
477 tile, | |
478 pixel_ref_id)); | |
479 } | |
480 | |
481 void TileManager::OnImageDecodingTaskCompleted(scoped_refptr<Tile> tile, | |
482 uint32_t pixel_ref_id) { | |
483 TRACE_EVENT0("cc", "TileManager::OnImageDecoded"); | |
484 pending_decode_tasks_.erase(pixel_ref_id); | |
485 | |
486 for (TileList::iterator it = tiles_with_image_decoding_tasks_.begin(); | |
487 it != tiles_with_image_decoding_tasks_.end(); ++it) { | |
488 std::list<skia::LazyPixelRef*>& pixel_refs = | |
489 (*it)->managed_state().pending_pixel_refs; | |
490 for (std::list<skia::LazyPixelRef*>::iterator pixel_it = | |
491 pixel_refs.begin(); pixel_it != pixel_refs.end(); ++pixel_it) { | |
492 if (pixel_ref_id == (*pixel_it)->getGenerationID()) { | |
493 pixel_refs.erase(pixel_it); | |
494 break; | |
495 } | |
496 } | |
497 } | |
498 DispatchMoreTasks(); | |
499 } | |
500 | |
395 void TileManager::DispatchOneRasterTask( | 501 void TileManager::DispatchOneRasterTask( |
396 RasterThread* thread, scoped_refptr<Tile> tile) { | 502 RasterThread* thread, scoped_refptr<Tile> tile) { |
397 TRACE_EVENT0("cc", "TileManager::DispatchOneRasterTask"); | 503 TRACE_EVENT0("cc", "TileManager::DispatchOneRasterTask"); |
398 ManagedTileState& managed_tile_state = tile->managed_state(); | 504 ManagedTileState& managed_tile_state = tile->managed_state(); |
399 DCHECK(managed_tile_state.can_use_gpu_memory); | 505 DCHECK(managed_tile_state.can_use_gpu_memory); |
400 scoped_ptr<ResourcePool::Resource> resource = | 506 scoped_ptr<ResourcePool::Resource> resource = |
401 resource_pool_->AcquireResource(tile->tile_size_.size(), tile->format_); | 507 resource_pool_->AcquireResource(tile->tile_size_.size(), tile->format_); |
402 resource_pool_->resource_provider()->acquirePixelBuffer(resource->id()); | 508 resource_pool_->resource_provider()->acquirePixelBuffer(resource->id()); |
403 | 509 |
404 managed_tile_state.resource_is_being_initialized = true; | 510 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()); | 545 resource_pool_->resource_provider()->unmapPixelBuffer(resource->id()); |
440 | 546 |
441 ManagedTileState& managed_tile_state = tile->managed_state(); | 547 ManagedTileState& managed_tile_state = tile->managed_state(); |
442 managed_tile_state.can_be_freed = true; | 548 managed_tile_state.can_be_freed = true; |
443 | 549 |
444 // Tile can be freed after the completion of the raster task. Call | 550 // Tile can be freed after the completion of the raster task. Call |
445 // AssignGpuMemoryToTiles() to re-assign gpu memory to highest priority | 551 // AssignGpuMemoryToTiles() to re-assign gpu memory to highest priority |
446 // tiles. The result of this could be that this tile is no longer | 552 // 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 | 553 // allowed to use gpu memory and in that case we need to abort |
448 // initialization and free all associated resources before calling | 554 // initialization and free all associated resources before calling |
449 // DispatchMoreRasterTasks(). | 555 // DispatchMoreTasks(). |
450 AssignGpuMemoryToTiles(); | 556 AssignGpuMemoryToTiles(); |
451 | 557 |
452 // Finish resource initialization if |can_use_gpu_memory| is true. | 558 // Finish resource initialization if |can_use_gpu_memory| is true. |
453 if (managed_tile_state.can_use_gpu_memory) { | 559 if (managed_tile_state.can_use_gpu_memory) { |
454 // The component order may be bgra if we're uploading bgra pixels to rgba | 560 // 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 | 561 // texture. Mark contents as swizzled if image component order is |
456 // different than texture format. | 562 // different than texture format. |
457 managed_tile_state.contents_swizzled = | 563 managed_tile_state.contents_swizzled = |
458 !PlatformColor::sameComponentOrder(tile->format_); | 564 !PlatformColor::sameComponentOrder(tile->format_); |
459 | 565 |
460 // Tile resources can't be freed until upload has completed. | 566 // Tile resources can't be freed until upload has completed. |
461 managed_tile_state.can_be_freed = false; | 567 managed_tile_state.can_be_freed = false; |
462 | 568 |
463 resource_pool_->resource_provider()->beginSetPixels(resource->id()); | 569 resource_pool_->resource_provider()->beginSetPixels(resource->id()); |
464 managed_tile_state.resource = resource.Pass(); | 570 managed_tile_state.resource = resource.Pass(); |
465 tiles_with_pending_set_pixels_.push(tile); | 571 tiles_with_pending_set_pixels_.push(tile); |
466 | 572 |
467 ScheduleCheckForCompletedSetPixels(); | 573 ScheduleCheckForCompletedSetPixels(); |
468 } else { | 574 } else { |
469 resource_pool_->resource_provider()->releasePixelBuffer(resource->id()); | 575 resource_pool_->resource_provider()->releasePixelBuffer(resource->id()); |
470 resource_pool_->ReleaseResource(resource.Pass()); | 576 resource_pool_->ReleaseResource(resource.Pass()); |
471 managed_tile_state.resource_is_being_initialized = false; | 577 managed_tile_state.resource_is_being_initialized = false; |
472 } | 578 } |
473 | 579 DispatchMoreTasks(); |
474 DispatchMoreRasterTasks(); | |
475 } | 580 } |
476 | 581 |
477 void TileManager::DidFinishTileInitialization(Tile* tile) { | 582 void TileManager::DidFinishTileInitialization(Tile* tile) { |
478 ManagedTileState& managed_tile_state = tile->managed_state(); | 583 ManagedTileState& managed_tile_state = tile->managed_state(); |
479 DCHECK(managed_tile_state.resource); | 584 DCHECK(managed_tile_state.resource); |
480 managed_tile_state.resource_is_being_initialized = false; | 585 managed_tile_state.resource_is_being_initialized = false; |
481 managed_tile_state.can_be_freed = true; | 586 managed_tile_state.can_be_freed = true; |
482 } | 587 } |
483 | 588 |
484 } | 589 } |
OLD | NEW |