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

Unified 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 side-by-side diff with in-line comments
Download patch
« no previous file with comments | « cc/tile_manager.h ('k') | skia/skia.gyp » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: cc/tile_manager.cc
diff --git a/cc/tile_manager.cc b/cc/tile_manager.cc
index 932c2a836d4181fd8c6f099fceaf76c5e223bbf4..06b5090ccfcf5407a7a4bfc2ab7641dd42b4d263 100644
--- a/cc/tile_manager.cc
+++ b/cc/tile_manager.cc
@@ -5,6 +5,7 @@
#include "cc/tile_manager.h"
#include <algorithm>
+#include <set>
#include "base/bind.h"
#include "base/command_line.h"
@@ -66,6 +67,16 @@ class RasterThread : public base::Thread {
base::Bind(&RasterThread::RunReply, base::Unretained(this), reply));
}
+ void PostImageDecodingTaskAndReply(const tracked_objects::Location& from_here,
+ skia::LazyPixelRef* pixel_ref,
+ const base::Closure& reply) {
+ ++num_pending_tasks_;
+ message_loop_proxy()->PostTaskAndReply(
+ from_here,
+ base::Bind(&RunImageDecodeTask, base::Unretained(pixel_ref)),
+ base::Bind(&RasterThread::RunReply, base::Unretained(this), reply));
+ }
+
private:
static void RunRasterTask(PicturePileImpl* picture_pile,
uint8_t* mapped_buffer,
@@ -87,6 +98,11 @@ class RasterThread : public base::Thread {
stats);
}
+ static void RunImageDecodeTask(skia::LazyPixelRef* pixel_ref) {
+ TRACE_EVENT0("cc", "RasterThread::RunImageDecodeTask");
+ pixel_ref->Decode();
+ }
+
void RunReply(const base::Closure& reply) {
--num_pending_tasks_;
reply.Run();
@@ -101,7 +117,8 @@ ManagedTileState::ManagedTileState()
: can_use_gpu_memory(false),
can_be_freed(true),
resource_is_being_initialized(false),
- contents_swizzled(false) {
+ contents_swizzled(false),
+ need_to_gather_pixel_refs(true) {
}
ManagedTileState::~ManagedTileState() {
@@ -284,7 +301,7 @@ void TileManager::ManageTiles() {
AssignGpuMemoryToTiles();
// Finally, kick the rasterizer.
- DispatchMoreRasterTasks();
+ DispatchMoreTasks();
}
void TileManager::CheckForCompletedSetPixels() {
@@ -332,6 +349,15 @@ void TileManager::AssignGpuMemoryToTiles() {
tiles_that_need_to_be_rasterized_.begin(),
tiles_that_need_to_be_rasterized_.end());
+ // Record all the tiles in the image decoding list. A tile will not be
+ // inserted to the rasterizer queue if it is waiting for image decoding.
+ std::set<Tile*> image_decoding_tile_set;
+ for (std::list<Tile*>::iterator it = tiles_with_image_decoding_tasks_.begin();
+ it != tiles_with_image_decoding_tasks_.end(); ++it) {
+ image_decoding_tile_set.insert(*it);
+ }
+ tiles_with_image_decoding_tasks_.clear();
+
size_t bytes_left = global_state_.memory_limit_in_bytes - unreleasable_bytes;
for (TileVector::iterator it = tiles_.begin(); it != tiles_.end(); ++it) {
Tile* tile = *it;
@@ -352,8 +378,12 @@ void TileManager::AssignGpuMemoryToTiles() {
bytes_left -= tile_bytes;
managed_tile_state.can_use_gpu_memory = true;
if (!managed_tile_state.resource &&
- !managed_tile_state.resource_is_being_initialized)
- tiles_that_need_to_be_rasterized_.push_back(tile);
+ !managed_tile_state.resource_is_being_initialized) {
+ if (image_decoding_tile_set.end() != image_decoding_tile_set.find(tile))
+ tiles_with_image_decoding_tasks_.push_back(tile);
+ else
+ tiles_that_need_to_be_rasterized_.push_back(tile);
+ }
}
// Reverse two tiles_that_need_* vectors such that pop_back gets
@@ -370,28 +400,125 @@ void TileManager::FreeResourcesForTile(Tile* tile) {
resource_pool_->ReleaseResource(managed_tile_state.resource.Pass());
}
-void TileManager::DispatchMoreRasterTasks() {
- while (!tiles_that_need_to_be_rasterized_.empty()) {
- RasterThread* thread = 0;
-
- for (RasterThreadVector::iterator it = raster_threads_.begin();
- it != raster_threads_.end(); ++it) {
- if ((*it)->num_pending_tasks() == kNumPendingRasterTasksPerThread)
- continue;
- // Check if this is the best thread we've found so far.
- if (!thread || (*it)->num_pending_tasks() < thread->num_pending_tasks())
- thread = *it;
- }
+RasterThread* TileManager::GetFreeRasterThread() {
+ RasterThread* thread = 0;
+ for (RasterThreadVector::iterator it = raster_threads_.begin();
+ it != raster_threads_.end(); ++it) {
+ if ((*it)->num_pending_tasks() == kNumPendingRasterTasksPerThread)
+ continue;
+ // Check if this is the best thread we've found so far.
+ if (!thread || (*it)->num_pending_tasks() < thread->num_pending_tasks())
+ thread = *it;
+ }
+ return thread;
+}
- // Stop dispatching tasks when all threads are busy.
- if (!thread)
+void TileManager::DispatchMoreTasks() {
+ // Because tiles in the image decoding list have higher priorities, we
+ // need to process those tiles first before we start to handle the tiles
+ // in the need_to_be_rasterized queue.
+ std::list<Tile*>::iterator it = tiles_with_image_decoding_tasks_.begin();
+ while (it != tiles_with_image_decoding_tasks_.end()) {
+ DispatchImageDecodingTasksForTile(*it);
+ ManagedTileState& managed_state = (*it)->managed_state();
+ if (managed_state.pending_pixel_refs.empty()) {
+ RasterThread* thread = GetFreeRasterThread();
+ if (!thread)
return;
+ DispatchOneRasterTask(thread, *it);
+ tiles_with_image_decoding_tasks_.erase(it++);
+ } else {
+ ++it;
+ }
+ }
- DispatchOneRasterTask(thread, tiles_that_need_to_be_rasterized_.back());
+ // Process all tiles in the need_to_be_rasterized queue. If a tile has
+ // image decoding tasks, put it to the back of the image decoding list.
+ while (!tiles_that_need_to_be_rasterized_.empty()) {
+ Tile* tile = tiles_that_need_to_be_rasterized_.back();
+ DispatchImageDecodingTasksForTile(tile);
+ ManagedTileState& managed_state = tile->managed_state();
+ if (!managed_state.pending_pixel_refs.empty()) {
+ tiles_with_image_decoding_tasks_.push_back(tile);
+ } else {
+ RasterThread* thread = GetFreeRasterThread();
+ if (!thread)
+ return;
+ DispatchOneRasterTask(thread, tile);
+ }
tiles_that_need_to_be_rasterized_.pop_back();
}
}
+void TileManager::DispatchImageDecodingTasksForTile(Tile* tile) {
+ ManagedTileState& managed_state = tile->managed_state();
+ if (managed_state.need_to_gather_pixel_refs) {
+ TRACE_EVENT0("cc",
+ "TileManager::DispatchImageDecodingTaskForTile: Gather PixelRefs");
+ const_cast<PicturePileImpl *>(tile->picture_pile())->GatherPixelRefs(
+ tile->content_rect_, managed_state.pending_pixel_refs);
+ managed_state.need_to_gather_pixel_refs = false;
+ }
+
+ std::list<skia::LazyPixelRef*>& pending_pixel_refs =
+ tile->managed_state().pending_pixel_refs;
+ std::list<skia::LazyPixelRef*>::iterator it = pending_pixel_refs.begin();
+ while (it != pending_pixel_refs.end()) {
+ if (pending_decode_tasks_.end() != pending_decode_tasks_.find(
+ (*it)->getGenerationID())) {
+ ++it;
+ continue;
+ }
+ // TODO(qinmin): passing correct image size to PrepareToDecode().
+ if ((*it)->PrepareToDecode(skia::LazyPixelRef::PrepareParams())) {
+ pending_pixel_refs.erase(it++);
+ } else {
+ RasterThread* thread = GetFreeRasterThread();
+ if (thread)
+ DispatchOneImageDecodingTask(thread, tile, *it);
+ ++it;
+ }
+ }
+}
+
+void TileManager::DispatchOneImageDecodingTask(RasterThread* thread,
+ scoped_refptr<Tile> tile,
+ skia::LazyPixelRef* pixel_ref) {
+ TRACE_EVENT0("cc", "TileManager::DispatchOneImageDecodingTask");
+ uint32_t pixel_ref_id = pixel_ref->getGenerationID();
+ DCHECK(pending_decode_tasks_.end() ==
+ pending_decode_tasks_.find(pixel_ref_id));
+ pending_decode_tasks_[pixel_ref_id] = pixel_ref;
+
+ thread->PostImageDecodingTaskAndReply(
+ FROM_HERE,
+ pixel_ref,
+ base::Bind(&TileManager::OnImageDecodingTaskCompleted,
+ base::Unretained(this),
+ tile,
+ pixel_ref_id));
+}
+
+void TileManager::OnImageDecodingTaskCompleted(scoped_refptr<Tile> tile,
+ uint32_t pixel_ref_id) {
+ TRACE_EVENT0("cc", "TileManager::OnImageDecoded");
+ pending_decode_tasks_.erase(pixel_ref_id);
+
+ for (TileList::iterator it = tiles_with_image_decoding_tasks_.begin();
+ it != tiles_with_image_decoding_tasks_.end(); ++it) {
+ std::list<skia::LazyPixelRef*>& pixel_refs =
+ (*it)->managed_state().pending_pixel_refs;
+ for (std::list<skia::LazyPixelRef*>::iterator pixel_it =
+ pixel_refs.begin(); pixel_it != pixel_refs.end(); ++pixel_it) {
+ if (pixel_ref_id == (*pixel_it)->getGenerationID()) {
+ pixel_refs.erase(pixel_it);
+ break;
+ }
+ }
+ }
+ DispatchMoreTasks();
+}
+
void TileManager::DispatchOneRasterTask(
RasterThread* thread, scoped_refptr<Tile> tile) {
TRACE_EVENT0("cc", "TileManager::DispatchOneRasterTask");
@@ -446,7 +573,7 @@ void TileManager::OnRasterTaskCompleted(
// tiles. The result of this could be that this tile is no longer
// allowed to use gpu memory and in that case we need to abort
// initialization and free all associated resources before calling
- // DispatchMoreRasterTasks().
+ // DispatchMoreTasks().
AssignGpuMemoryToTiles();
// Finish resource initialization if |can_use_gpu_memory| is true.
@@ -470,8 +597,7 @@ void TileManager::OnRasterTaskCompleted(
resource_pool_->ReleaseResource(resource.Pass());
managed_tile_state.resource_is_being_initialized = false;
}
-
- DispatchMoreRasterTasks();
+ DispatchMoreTasks();
}
void TileManager::DidFinishTileInitialization(Tile* tile) {
« 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