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

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: 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
« cc/tile_manager.h ('K') | « 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 5eface4e7d9bfc6fa4e6fdadcd503ed2f02d368e..1b8237fc36bca99aa65d71efe55680eb5090a51e 100644
--- a/cc/tile_manager.cc
+++ b/cc/tile_manager.cc
@@ -12,11 +12,13 @@
#include "base/logging.h"
#include "base/string_number_conversions.h"
#include "base/threading/sequenced_worker_pool.h"
+#include "cc/image.h"
#include "cc/platform_color.h"
#include "cc/rendering_stats.h"
#include "cc/resource_pool.h"
#include "cc/switches.h"
#include "cc/tile.h"
+#include "skia/ext/lazy_pixel_ref.h"
#include "third_party/skia/include/core/SkDevice.h"
namespace {
@@ -160,6 +162,8 @@ void TileManager::ManageTiles() {
const bool smoothness_takes_priority = global_state_.smoothness_takes_priority;
+ decoding_progress_.clear();
reveman 2012/12/05 19:48:46 ManageTiles() might be called while images are bei
qinmin 2012/12/07 05:06:28 Since this variable is changed to keep track of al
+
// Bin into three categories of tiles: things we need now, things we need soon, and eventually
for (TileVector::iterator it = tiles_.begin(); it != tiles_.end(); ++it) {
Tile* tile = *it;
@@ -196,6 +200,15 @@ void TileManager::ManageTiles() {
}
mts.bin = EVENTUALLY_BIN;
+
+ // Update all the SkPixelRefs this tile intersects.
+ mts.pixel_refs.clear();
+ mts.pixel_refs =
+ const_cast<PicturePileImpl *>(tile->picture_pile())->GatherPixelRefs(
+ tile->rect_inside_picture_);
+ for (std::vector<SkPixelRef*>::iterator it = mts.pixel_refs.begin();
+ it != mts.pixel_refs.end(); ++it)
+ decoding_progress_[*it] = NOT_STARTED;
reveman 2012/12/05 19:48:46 The pixel refs for a tile should never change, rig
qinmin 2012/12/07 05:06:28 Changed this to only get the skpixelref informatio
}
// Memory limit policy works by mapping some bin states to the NEVER bin.
@@ -300,17 +313,91 @@ void TileManager::FreeResourcesForTile(Tile* tile) {
}
void TileManager::DispatchMoreRasterTasks() {
- while (!tiles_that_need_to_be_rasterized_.empty()) {
- int max_pending_tasks = kNumPendingRasterTasksPerThread *
- kMaxRasterThreads;
-
+ int max_pending_tasks = kNumPendingRasterTasksPerThread *
+ kMaxRasterThreads;
+ bool all_tiles_waiting_for_decoder = false;
+ while (!tiles_that_need_to_be_rasterized_.empty() &&
+ !all_tiles_waiting_for_decoder) {
// Stop dispatching raster tasks when too many are pending.
if (pending_raster_tasks_ >= max_pending_tasks)
break;
+ all_tiles_waiting_for_decoder = true;
+ // TODO(qinmin): Use a separate queue for tiles that are doing image
+ // decoding. However, we need to find a good way to keep track of
+ // the tile priority. Otherwise, one queue may starve the other queue.
+ TileVector::reverse_iterator it;
+ for (it = tiles_that_need_to_be_rasterized_.rbegin();
+ it != tiles_that_need_to_be_rasterized_.rend(); ++it) {
+ std::vector<SkPixelRef*> pixel_refs;
+ if (HasUndecodedImages(*it, pixel_refs)) {
+ if (pixel_refs.empty())
+ continue;
+ for (std::vector<SkPixelRef*>::iterator it = pixel_refs.begin();
+ it != pixel_refs.end(); ++it) {
+ SpawnImageDecodingTask(*it);
+ // If we are reaching the task limit, just finish here and wait for
+ // tasks to finish.
+ if (pending_raster_tasks_ >= max_pending_tasks)
+ return;
+ }
+ } else {
+ DispatchOneRasterTask(*it);
+ all_tiles_waiting_for_decoder = false;
+ // Be cautious that we are erasing a reverse iterator.
+ tiles_that_need_to_be_rasterized_.erase(--it.base());
+ break;
+ }
+ }
reveman 2012/12/05 19:48:46 I think we're starting to do too much in this func
qinmin 2012/12/07 05:06:28 Done. Now all the jobs waiting on image decoding g
+ }
+}
- DispatchOneRasterTask(tiles_that_need_to_be_rasterized_.back());
- tiles_that_need_to_be_rasterized_.pop_back();
+bool TileManager::HasUndecodedImages(Tile* tile,
reveman 2012/12/05 19:48:46 Could we just remove SkPixelRefs from managed_stat
reveman 2012/12/05 20:28:35 I guess we still need a map with all the pixel ref
qinmin 2012/12/07 05:06:28 we cannot remove SkPixelRef if the decoding task j
+ std::vector<SkPixelRef*>& unstarted) {
+ bool has_undecoded_images = false;
+ SkPixelRef* decode_not_started = 0;
+ ManagedTileState& managed_state = tile->managed_state();
+ for (std::vector<SkPixelRef*>::iterator it = managed_state.pixel_refs.begin();
+ it != managed_state.pixel_refs.end(); ++it) {
+ bool not_started = false;
+ switch(decoding_progress_[*it]) {
+ case FINISHED:
+ break;
+ case NOT_STARTED:
+ not_started = true;
+ case IN_PROGRESS:
+ scoped_refptr<Image> image(Image::Create(*it));
+ // If image is already in cache, don't spawn decode task.
+ if (!image->PrepareToDecode()) {
+ has_undecoded_images = true;
+ if (not_started)
+ unstarted.push_back(*it);
+ }
+ }
}
+ return has_undecoded_images;
+}
+
+void TileManager::SpawnImageDecodingTask(SkPixelRef* pixel_ref) {
+ TRACE_EVENT0("cc", "TileManager::SpawnImageDecodingTask");
+ scoped_refptr<Image> image(Image::Create(pixel_ref));
reveman 2012/12/05 19:48:46 Doesn't look like image need to be ref counted. Ca
reveman 2012/12/05 20:28:35 Would it make sense to add a ScopedPtrHashMap<SkPi
qinmin 2012/12/07 05:06:28 Removed the image class. However, I am not sure wh
+ // Kicking off a image decode job.
+ ++pending_raster_tasks_;
+ worker_pool_->GetTaskRunnerWithShutdownBehavior(
+ base::SequencedWorkerPool::SKIP_ON_SHUTDOWN)->PostTaskAndReply(
+ FROM_HERE,
+ base::Bind(&Image::Decode,
Alpha Left Google 2012/12/05 20:24:28 This is fine now but just be aware that after this
qinmin 2012/12/07 05:06:28 Yes, redecoding can be problematic if the cache go
+ image),
+ base::Bind(&TileManager::OnImageDecoded,
+ base::Unretained(this),
reveman 2012/12/05 19:48:46 Each decoding task is associated with a tile and d
qinmin 2012/12/07 05:06:28 I think when we kick off the image decoder, we alw
+ image));
+ decoding_progress_[pixel_ref] = IN_PROGRESS;
+}
+
+void TileManager::OnImageDecoded(scoped_refptr<Image> image) {
+ TRACE_EVENT0("cc", "TileManager::OnImageDecoded");
+ --pending_raster_tasks_;
+ decoding_progress_[image->pixel_ref()] = FINISHED;
+ DispatchMoreRasterTasks();
}
void TileManager::DispatchOneRasterTask(scoped_refptr<Tile> tile) {
« cc/tile_manager.h ('K') | « cc/tile_manager.h ('k') | skia/skia.gyp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698