Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(274)

Side by Side Diff: cc/tile_manager.cc

Issue 11453014: Implement the logic to kick off image decoding jobs for TileManager (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: fix for win_rel trybot Created 8 years ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « cc/tile_manager.h ('k') | skia/skia.gyp » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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 9
9 #include "base/bind.h" 10 #include "base/bind.h"
10 #include "base/command_line.h" 11 #include "base/command_line.h"
11 #include "base/debug/trace_event.h" 12 #include "base/debug/trace_event.h"
12 #include "base/logging.h" 13 #include "base/logging.h"
13 #include "base/stringprintf.h" 14 #include "base/stringprintf.h"
14 #include "base/threading/thread.h" 15 #include "base/threading/thread.h"
15 #include "cc/platform_color.h" 16 #include "cc/platform_color.h"
16 #include "cc/rendering_stats.h" 17 #include "cc/rendering_stats.h"
17 #include "cc/resource_pool.h" 18 #include "cc/resource_pool.h"
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after
59 from_here, 60 from_here,
60 base::Bind(&RunRasterTask, 61 base::Bind(&RunRasterTask,
61 base::Unretained(picture_pile), 62 base::Unretained(picture_pile),
62 mapped_buffer, 63 mapped_buffer,
63 rect, 64 rect,
64 contents_scale, 65 contents_scale,
65 stats), 66 stats),
66 base::Bind(&RasterThread::RunReply, base::Unretained(this), reply)); 67 base::Bind(&RasterThread::RunReply, base::Unretained(this), reply));
67 } 68 }
68 69
70 void PostImageDecodingTaskAndReply(const tracked_objects::Location& from_here,
71 skia::LazyPixelRef* pixel_ref,
72 const base::Closure& reply) {
73 ++num_pending_tasks_;
74 message_loop_proxy()->PostTaskAndReply(
75 from_here,
76 base::Bind(&RunImageDecodeTask, base::Unretained(pixel_ref)),
77 base::Bind(&RasterThread::RunReply, base::Unretained(this), reply));
78 }
79
69 private: 80 private:
70 static void RunRasterTask(PicturePileImpl* picture_pile, 81 static void RunRasterTask(PicturePileImpl* picture_pile,
71 uint8_t* mapped_buffer, 82 uint8_t* mapped_buffer,
72 const gfx::Rect& rect, 83 const gfx::Rect& rect,
73 float contents_scale, 84 float contents_scale,
74 RenderingStats* stats) { 85 RenderingStats* stats) {
75 TRACE_EVENT0("cc", "RasterThread::RunRasterTask"); 86 TRACE_EVENT0("cc", "RasterThread::RunRasterTask");
76 DCHECK(picture_pile); 87 DCHECK(picture_pile);
77 DCHECK(mapped_buffer); 88 DCHECK(mapped_buffer);
78 SkBitmap bitmap; 89 SkBitmap bitmap;
79 bitmap.setConfig(SkBitmap::kARGB_8888_Config, rect.width(), rect.height()); 90 bitmap.setConfig(SkBitmap::kARGB_8888_Config, rect.width(), rect.height());
80 bitmap.setPixels(mapped_buffer); 91 bitmap.setPixels(mapped_buffer);
81 SkDevice device(bitmap); 92 SkDevice device(bitmap);
82 SkCanvas canvas(&device); 93 SkCanvas canvas(&device);
83 picture_pile->Raster( 94 picture_pile->Raster(
84 &canvas, 95 &canvas,
85 rect, 96 rect,
86 contents_scale, 97 contents_scale,
87 stats); 98 stats);
88 } 99 }
89 100
101 static void RunImageDecodeTask(skia::LazyPixelRef* pixel_ref) {
102 TRACE_EVENT0("cc", "RasterThread::RunImageDecodeTask");
103 pixel_ref->Decode();
104 }
105
90 void RunReply(const base::Closure& reply) { 106 void RunReply(const base::Closure& reply) {
91 --num_pending_tasks_; 107 --num_pending_tasks_;
92 reply.Run(); 108 reply.Run();
93 } 109 }
94 110
95 int num_pending_tasks_; 111 int num_pending_tasks_;
96 112
97 DISALLOW_COPY_AND_ASSIGN(RasterThread); 113 DISALLOW_COPY_AND_ASSIGN(RasterThread);
98 }; 114 };
99 115
100 ManagedTileState::ManagedTileState() 116 ManagedTileState::ManagedTileState()
101 : can_use_gpu_memory(false), 117 : can_use_gpu_memory(false),
102 can_be_freed(true), 118 can_be_freed(true),
103 resource_is_being_initialized(false), 119 resource_is_being_initialized(false),
104 contents_swizzled(false) { 120 contents_swizzled(false),
121 need_to_gather_pixel_refs(true) {
105 } 122 }
106 123
107 ManagedTileState::~ManagedTileState() { 124 ManagedTileState::~ManagedTileState() {
108 DCHECK(!resource); 125 DCHECK(!resource);
109 DCHECK(!resource_is_being_initialized); 126 DCHECK(!resource_is_being_initialized);
110 } 127 }
111 128
112 TileManager::TileManager( 129 TileManager::TileManager(
113 TileManagerClient* client, 130 TileManagerClient* client,
114 ResourceProvider* resource_provider, 131 ResourceProvider* resource_provider,
(...skipping 162 matching lines...) Expand 10 before | Expand all | Expand 10 after
277 tile->managed_state().bin = bin; 294 tile->managed_state().bin = bin;
278 } 295 }
279 296
280 // Sort by bin. 297 // Sort by bin.
281 std::sort(tiles_.begin(), tiles_.end(), BinComparator()); 298 std::sort(tiles_.begin(), tiles_.end(), BinComparator());
282 299
283 // Assign gpu memory and determine what tiles need to be rasterized. 300 // Assign gpu memory and determine what tiles need to be rasterized.
284 AssignGpuMemoryToTiles(); 301 AssignGpuMemoryToTiles();
285 302
286 // Finally, kick the rasterizer. 303 // Finally, kick the rasterizer.
287 DispatchMoreRasterTasks(); 304 DispatchMoreTasks();
288 } 305 }
289 306
290 void TileManager::CheckForCompletedSetPixels() { 307 void TileManager::CheckForCompletedSetPixels() {
291 check_for_completed_set_pixels_pending_ = false; 308 check_for_completed_set_pixels_pending_ = false;
292 309
293 while (!tiles_with_pending_set_pixels_.empty()) { 310 while (!tiles_with_pending_set_pixels_.empty()) {
294 Tile* tile = tiles_with_pending_set_pixels_.front(); 311 Tile* tile = tiles_with_pending_set_pixels_.front();
295 DCHECK(tile->managed_state().resource); 312 DCHECK(tile->managed_state().resource);
296 313
297 // Set pixel tasks complete in the order they are posted. 314 // Set pixel tasks complete in the order they are posted.
(...skipping 27 matching lines...) Expand all
325 if (!tile->managed_state().can_be_freed) 342 if (!tile->managed_state().can_be_freed)
326 unreleasable_bytes += tile->bytes_consumed_if_allocated(); 343 unreleasable_bytes += tile->bytes_consumed_if_allocated();
327 } 344 }
328 345
329 // Now give memory out to the tiles until we're out, and build 346 // Now give memory out to the tiles until we're out, and build
330 // the needs-to-be-rasterized queue. 347 // the needs-to-be-rasterized queue.
331 tiles_that_need_to_be_rasterized_.erase( 348 tiles_that_need_to_be_rasterized_.erase(
332 tiles_that_need_to_be_rasterized_.begin(), 349 tiles_that_need_to_be_rasterized_.begin(),
333 tiles_that_need_to_be_rasterized_.end()); 350 tiles_that_need_to_be_rasterized_.end());
334 351
352 // Record all the tiles in the image decoding list. A tile will not be
353 // inserted to the rasterizer queue if it is waiting for image decoding.
354 std::set<Tile*> image_decoding_tile_set;
355 for (std::list<Tile*>::iterator it = tiles_with_image_decoding_tasks_.begin();
356 it != tiles_with_image_decoding_tasks_.end(); ++it) {
357 image_decoding_tile_set.insert(*it);
358 }
359 tiles_with_image_decoding_tasks_.clear();
360
335 size_t bytes_left = global_state_.memory_limit_in_bytes - unreleasable_bytes; 361 size_t bytes_left = global_state_.memory_limit_in_bytes - unreleasable_bytes;
336 for (TileVector::iterator it = tiles_.begin(); it != tiles_.end(); ++it) { 362 for (TileVector::iterator it = tiles_.begin(); it != tiles_.end(); ++it) {
337 Tile* tile = *it; 363 Tile* tile = *it;
338 size_t tile_bytes = tile->bytes_consumed_if_allocated(); 364 size_t tile_bytes = tile->bytes_consumed_if_allocated();
339 ManagedTileState& managed_tile_state = tile->managed_state(); 365 ManagedTileState& managed_tile_state = tile->managed_state();
340 if (!managed_tile_state.can_be_freed) 366 if (!managed_tile_state.can_be_freed)
341 continue; 367 continue;
342 if (managed_tile_state.bin == NEVER_BIN) { 368 if (managed_tile_state.bin == NEVER_BIN) {
343 managed_tile_state.can_use_gpu_memory = false; 369 managed_tile_state.can_use_gpu_memory = false;
344 FreeResourcesForTile(tile); 370 FreeResourcesForTile(tile);
345 continue; 371 continue;
346 } 372 }
347 if (tile_bytes > bytes_left) { 373 if (tile_bytes > bytes_left) {
348 managed_tile_state.can_use_gpu_memory = false; 374 managed_tile_state.can_use_gpu_memory = false;
349 FreeResourcesForTile(tile); 375 FreeResourcesForTile(tile);
350 continue; 376 continue;
351 } 377 }
352 bytes_left -= tile_bytes; 378 bytes_left -= tile_bytes;
353 managed_tile_state.can_use_gpu_memory = true; 379 managed_tile_state.can_use_gpu_memory = true;
354 if (!managed_tile_state.resource && 380 if (!managed_tile_state.resource &&
355 !managed_tile_state.resource_is_being_initialized) 381 !managed_tile_state.resource_is_being_initialized) {
356 tiles_that_need_to_be_rasterized_.push_back(tile); 382 if (image_decoding_tile_set.end() != image_decoding_tile_set.find(tile))
383 tiles_with_image_decoding_tasks_.push_back(tile);
384 else
385 tiles_that_need_to_be_rasterized_.push_back(tile);
386 }
357 } 387 }
358 388
359 // Reverse two tiles_that_need_* vectors such that pop_back gets 389 // Reverse two tiles_that_need_* vectors such that pop_back gets
360 // the highest priority tile. 390 // the highest priority tile.
361 std::reverse( 391 std::reverse(
362 tiles_that_need_to_be_rasterized_.begin(), 392 tiles_that_need_to_be_rasterized_.begin(),
363 tiles_that_need_to_be_rasterized_.end()); 393 tiles_that_need_to_be_rasterized_.end());
364 } 394 }
365 395
366 void TileManager::FreeResourcesForTile(Tile* tile) { 396 void TileManager::FreeResourcesForTile(Tile* tile) {
367 ManagedTileState& managed_tile_state = tile->managed_state(); 397 ManagedTileState& managed_tile_state = tile->managed_state();
368 DCHECK(managed_tile_state.can_be_freed); 398 DCHECK(managed_tile_state.can_be_freed);
369 if (managed_tile_state.resource) 399 if (managed_tile_state.resource)
370 resource_pool_->ReleaseResource(managed_tile_state.resource.Pass()); 400 resource_pool_->ReleaseResource(managed_tile_state.resource.Pass());
371 } 401 }
372 402
373 void TileManager::DispatchMoreRasterTasks() { 403 RasterThread* TileManager::GetFreeRasterThread() {
404 RasterThread* thread = 0;
405 for (RasterThreadVector::iterator it = raster_threads_.begin();
406 it != raster_threads_.end(); ++it) {
407 if ((*it)->num_pending_tasks() == kNumPendingRasterTasksPerThread)
408 continue;
409 // Check if this is the best thread we've found so far.
410 if (!thread || (*it)->num_pending_tasks() < thread->num_pending_tasks())
411 thread = *it;
412 }
413 return thread;
414 }
415
416 void TileManager::DispatchMoreTasks() {
417 // Because tiles in the image decoding list have higher priorities, we
418 // need to process those tiles first before we start to handle the tiles
419 // in the need_to_be_rasterized queue.
420 std::list<Tile*>::iterator it = tiles_with_image_decoding_tasks_.begin();
421 while (it != tiles_with_image_decoding_tasks_.end()) {
422 DispatchImageDecodingTasksForTile(*it);
423 ManagedTileState& managed_state = (*it)->managed_state();
424 if (managed_state.pending_pixel_refs.empty()) {
425 RasterThread* thread = GetFreeRasterThread();
426 if (!thread)
427 return;
428 DispatchOneRasterTask(thread, *it);
429 tiles_with_image_decoding_tasks_.erase(it++);
430 } else {
431 ++it;
432 }
433 }
434
435 // Process all tiles in the need_to_be_rasterized queue. If a tile has
436 // image decoding tasks, put it to the back of the image decoding list.
374 while (!tiles_that_need_to_be_rasterized_.empty()) { 437 while (!tiles_that_need_to_be_rasterized_.empty()) {
375 RasterThread* thread = 0; 438 Tile* tile = tiles_that_need_to_be_rasterized_.back();
376 439 DispatchImageDecodingTasksForTile(tile);
377 for (RasterThreadVector::iterator it = raster_threads_.begin(); 440 ManagedTileState& managed_state = tile->managed_state();
378 it != raster_threads_.end(); ++it) { 441 if (!managed_state.pending_pixel_refs.empty()) {
379 if ((*it)->num_pending_tasks() == kNumPendingRasterTasksPerThread) 442 tiles_with_image_decoding_tasks_.push_back(tile);
380 continue; 443 } else {
381 // Check if this is the best thread we've found so far. 444 RasterThread* thread = GetFreeRasterThread();
382 if (!thread || (*it)->num_pending_tasks() < thread->num_pending_tasks()) 445 if (!thread)
383 thread = *it; 446 return;
447 DispatchOneRasterTask(thread, tile);
384 } 448 }
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(); 449 tiles_that_need_to_be_rasterized_.pop_back();
392 } 450 }
393 } 451 }
394 452
453 void TileManager::DispatchImageDecodingTasksForTile(Tile* tile) {
454 ManagedTileState& managed_state = tile->managed_state();
455 if (managed_state.need_to_gather_pixel_refs) {
456 TRACE_EVENT0("cc",
457 "TileManager::DispatchImageDecodingTaskForTile: Gather PixelRefs");
458 const_cast<PicturePileImpl *>(tile->picture_pile())->GatherPixelRefs(
459 tile->content_rect_, managed_state.pending_pixel_refs);
460 managed_state.need_to_gather_pixel_refs = false;
461 }
462
463 std::list<skia::LazyPixelRef*>& pending_pixel_refs =
464 tile->managed_state().pending_pixel_refs;
465 std::list<skia::LazyPixelRef*>::iterator it = pending_pixel_refs.begin();
466 while (it != pending_pixel_refs.end()) {
467 if (pending_decode_tasks_.end() != pending_decode_tasks_.find(
468 (*it)->getGenerationID())) {
469 ++it;
470 continue;
471 }
472 // TODO(qinmin): passing correct image size to PrepareToDecode().
473 if ((*it)->PrepareToDecode(skia::LazyPixelRef::PrepareParams())) {
474 pending_pixel_refs.erase(it++);
475 } else {
476 RasterThread* thread = GetFreeRasterThread();
477 if (thread)
478 DispatchOneImageDecodingTask(thread, tile, *it);
479 ++it;
480 }
481 }
482 }
483
484 void TileManager::DispatchOneImageDecodingTask(RasterThread* thread,
485 scoped_refptr<Tile> tile,
486 skia::LazyPixelRef* pixel_ref) {
487 TRACE_EVENT0("cc", "TileManager::DispatchOneImageDecodingTask");
488 uint32_t pixel_ref_id = pixel_ref->getGenerationID();
489 DCHECK(pending_decode_tasks_.end() ==
490 pending_decode_tasks_.find(pixel_ref_id));
491 pending_decode_tasks_[pixel_ref_id] = pixel_ref;
492
493 thread->PostImageDecodingTaskAndReply(
494 FROM_HERE,
495 pixel_ref,
496 base::Bind(&TileManager::OnImageDecodingTaskCompleted,
497 base::Unretained(this),
498 tile,
499 pixel_ref_id));
500 }
501
502 void TileManager::OnImageDecodingTaskCompleted(scoped_refptr<Tile> tile,
503 uint32_t pixel_ref_id) {
504 TRACE_EVENT0("cc", "TileManager::OnImageDecoded");
505 pending_decode_tasks_.erase(pixel_ref_id);
506
507 for (TileList::iterator it = tiles_with_image_decoding_tasks_.begin();
508 it != tiles_with_image_decoding_tasks_.end(); ++it) {
509 std::list<skia::LazyPixelRef*>& pixel_refs =
510 (*it)->managed_state().pending_pixel_refs;
511 for (std::list<skia::LazyPixelRef*>::iterator pixel_it =
512 pixel_refs.begin(); pixel_it != pixel_refs.end(); ++pixel_it) {
513 if (pixel_ref_id == (*pixel_it)->getGenerationID()) {
514 pixel_refs.erase(pixel_it);
515 break;
516 }
517 }
518 }
519 DispatchMoreTasks();
520 }
521
395 void TileManager::DispatchOneRasterTask( 522 void TileManager::DispatchOneRasterTask(
396 RasterThread* thread, scoped_refptr<Tile> tile) { 523 RasterThread* thread, scoped_refptr<Tile> tile) {
397 TRACE_EVENT0("cc", "TileManager::DispatchOneRasterTask"); 524 TRACE_EVENT0("cc", "TileManager::DispatchOneRasterTask");
398 ManagedTileState& managed_tile_state = tile->managed_state(); 525 ManagedTileState& managed_tile_state = tile->managed_state();
399 DCHECK(managed_tile_state.can_use_gpu_memory); 526 DCHECK(managed_tile_state.can_use_gpu_memory);
400 scoped_ptr<ResourcePool::Resource> resource = 527 scoped_ptr<ResourcePool::Resource> resource =
401 resource_pool_->AcquireResource(tile->tile_size_.size(), tile->format_); 528 resource_pool_->AcquireResource(tile->tile_size_.size(), tile->format_);
402 resource_pool_->resource_provider()->acquirePixelBuffer(resource->id()); 529 resource_pool_->resource_provider()->acquirePixelBuffer(resource->id());
403 530
404 managed_tile_state.resource_is_being_initialized = true; 531 managed_tile_state.resource_is_being_initialized = true;
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after
439 resource_pool_->resource_provider()->unmapPixelBuffer(resource->id()); 566 resource_pool_->resource_provider()->unmapPixelBuffer(resource->id());
440 567
441 ManagedTileState& managed_tile_state = tile->managed_state(); 568 ManagedTileState& managed_tile_state = tile->managed_state();
442 managed_tile_state.can_be_freed = true; 569 managed_tile_state.can_be_freed = true;
443 570
444 // Tile can be freed after the completion of the raster task. Call 571 // Tile can be freed after the completion of the raster task. Call
445 // AssignGpuMemoryToTiles() to re-assign gpu memory to highest priority 572 // AssignGpuMemoryToTiles() to re-assign gpu memory to highest priority
446 // tiles. The result of this could be that this tile is no longer 573 // 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 574 // allowed to use gpu memory and in that case we need to abort
448 // initialization and free all associated resources before calling 575 // initialization and free all associated resources before calling
449 // DispatchMoreRasterTasks(). 576 // DispatchMoreTasks().
450 AssignGpuMemoryToTiles(); 577 AssignGpuMemoryToTiles();
451 578
452 // Finish resource initialization if |can_use_gpu_memory| is true. 579 // Finish resource initialization if |can_use_gpu_memory| is true.
453 if (managed_tile_state.can_use_gpu_memory) { 580 if (managed_tile_state.can_use_gpu_memory) {
454 // The component order may be bgra if we're uploading bgra pixels to rgba 581 // 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 582 // texture. Mark contents as swizzled if image component order is
456 // different than texture format. 583 // different than texture format.
457 managed_tile_state.contents_swizzled = 584 managed_tile_state.contents_swizzled =
458 !PlatformColor::sameComponentOrder(tile->format_); 585 !PlatformColor::sameComponentOrder(tile->format_);
459 586
460 // Tile resources can't be freed until upload has completed. 587 // Tile resources can't be freed until upload has completed.
461 managed_tile_state.can_be_freed = false; 588 managed_tile_state.can_be_freed = false;
462 589
463 resource_pool_->resource_provider()->beginSetPixels(resource->id()); 590 resource_pool_->resource_provider()->beginSetPixels(resource->id());
464 managed_tile_state.resource = resource.Pass(); 591 managed_tile_state.resource = resource.Pass();
465 tiles_with_pending_set_pixels_.push(tile); 592 tiles_with_pending_set_pixels_.push(tile);
466 593
467 ScheduleCheckForCompletedSetPixels(); 594 ScheduleCheckForCompletedSetPixels();
468 } else { 595 } else {
469 resource_pool_->resource_provider()->releasePixelBuffer(resource->id()); 596 resource_pool_->resource_provider()->releasePixelBuffer(resource->id());
470 resource_pool_->ReleaseResource(resource.Pass()); 597 resource_pool_->ReleaseResource(resource.Pass());
471 managed_tile_state.resource_is_being_initialized = false; 598 managed_tile_state.resource_is_being_initialized = false;
472 } 599 }
473 600 DispatchMoreTasks();
474 DispatchMoreRasterTasks();
475 } 601 }
476 602
477 void TileManager::DidFinishTileInitialization(Tile* tile) { 603 void TileManager::DidFinishTileInitialization(Tile* tile) {
478 ManagedTileState& managed_tile_state = tile->managed_state(); 604 ManagedTileState& managed_tile_state = tile->managed_state();
479 DCHECK(managed_tile_state.resource); 605 DCHECK(managed_tile_state.resource);
480 managed_tile_state.resource_is_being_initialized = false; 606 managed_tile_state.resource_is_being_initialized = false;
481 managed_tile_state.can_be_freed = true; 607 managed_tile_state.can_be_freed = true;
482 } 608 }
483 609
484 } 610 }
OLDNEW
« no previous file with comments | « cc/tile_manager.h ('k') | skia/skia.gyp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698