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

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: 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
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 8
9 #include "base/bind.h" 9 #include "base/bind.h"
10 #include "base/command_line.h" 10 #include "base/command_line.h"
11 #include "base/debug/trace_event.h" 11 #include "base/debug/trace_event.h"
12 #include "base/logging.h" 12 #include "base/logging.h"
13 #include "base/string_number_conversions.h" 13 #include "base/string_number_conversions.h"
14 #include "base/threading/sequenced_worker_pool.h" 14 #include "base/threading/sequenced_worker_pool.h"
15 #include "cc/image.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"
18 #include "cc/switches.h" 19 #include "cc/switches.h"
19 #include "cc/tile.h" 20 #include "cc/tile.h"
21 #include "skia/ext/lazy_pixel_ref.h"
20 #include "third_party/skia/include/core/SkDevice.h" 22 #include "third_party/skia/include/core/SkDevice.h"
21 23
22 namespace { 24 namespace {
23 25
24 void RasterizeTile(cc::PicturePileImpl* picture_pile, 26 void RasterizeTile(cc::PicturePileImpl* picture_pile,
25 uint8_t* mapped_buffer, 27 uint8_t* mapped_buffer,
26 const gfx::Rect& rect, 28 const gfx::Rect& rect,
27 cc::RenderingStats* stats) { 29 cc::RenderingStats* stats) {
28 TRACE_EVENT0("cc", "RasterizeTile"); 30 TRACE_EVENT0("cc", "RasterizeTile");
29 DCHECK(mapped_buffer); 31 DCHECK(mapped_buffer);
(...skipping 123 matching lines...) Expand 10 before | Expand all | Expand 10 after
153 void TileManager::ManageTiles() { 155 void TileManager::ManageTiles() {
154 TRACE_EVENT0("cc", "TileManager::ManageTiles"); 156 TRACE_EVENT0("cc", "TileManager::ManageTiles");
155 manage_tiles_pending_ = false; 157 manage_tiles_pending_ = false;
156 158
157 // The amount of time for which we want to have prepainting coverage. 159 // The amount of time for which we want to have prepainting coverage.
158 const double prepainting_window_time_seconds = 1.0; 160 const double prepainting_window_time_seconds = 1.0;
159 const double backfling_guard_distance_pixels = 314.0; 161 const double backfling_guard_distance_pixels = 314.0;
160 162
161 const bool smoothness_takes_priority = global_state_.smoothness_takes_priority ; 163 const bool smoothness_takes_priority = global_state_.smoothness_takes_priority ;
162 164
165 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
166
163 // Bin into three categories of tiles: things we need now, things we need soon , and eventually 167 // Bin into three categories of tiles: things we need now, things we need soon , and eventually
164 for (TileVector::iterator it = tiles_.begin(); it != tiles_.end(); ++it) { 168 for (TileVector::iterator it = tiles_.begin(); it != tiles_.end(); ++it) {
165 Tile* tile = *it; 169 Tile* tile = *it;
166 ManagedTileState& mts = tile->managed_state(); 170 ManagedTileState& mts = tile->managed_state();
167 TilePriority prio; 171 TilePriority prio;
168 if (smoothness_takes_priority) 172 if (smoothness_takes_priority)
169 prio = tile->priority(ACTIVE_TREE); 173 prio = tile->priority(ACTIVE_TREE);
170 else 174 else
171 prio = tile->combined_priority(); 175 prio = tile->combined_priority();
172 176
(...skipping 16 matching lines...) Expand all
189 mts.bin = NOW_BIN; 193 mts.bin = NOW_BIN;
190 continue; 194 continue;
191 } 195 }
192 196
193 if (prio.time_to_needed_in_seconds() < prepainting_window_time_seconds) { 197 if (prio.time_to_needed_in_seconds() < prepainting_window_time_seconds) {
194 mts.bin = SOON_BIN; 198 mts.bin = SOON_BIN;
195 continue; 199 continue;
196 } 200 }
197 201
198 mts.bin = EVENTUALLY_BIN; 202 mts.bin = EVENTUALLY_BIN;
203
204 // Update all the SkPixelRefs this tile intersects.
205 mts.pixel_refs.clear();
206 mts.pixel_refs =
207 const_cast<PicturePileImpl *>(tile->picture_pile())->GatherPixelRefs(
208 tile->rect_inside_picture_);
209 for (std::vector<SkPixelRef*>::iterator it = mts.pixel_refs.begin();
210 it != mts.pixel_refs.end(); ++it)
211 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
199 } 212 }
200 213
201 // Memory limit policy works by mapping some bin states to the NEVER bin. 214 // Memory limit policy works by mapping some bin states to the NEVER bin.
202 TileManagerBin bin_map[NUM_BINS]; 215 TileManagerBin bin_map[NUM_BINS];
203 if (global_state_.memory_limit_policy == ALLOW_NOTHING) { 216 if (global_state_.memory_limit_policy == ALLOW_NOTHING) {
204 bin_map[NOW_BIN] = NEVER_BIN; 217 bin_map[NOW_BIN] = NEVER_BIN;
205 bin_map[SOON_BIN] = NEVER_BIN; 218 bin_map[SOON_BIN] = NEVER_BIN;
206 bin_map[EVENTUALLY_BIN] = NEVER_BIN; 219 bin_map[EVENTUALLY_BIN] = NEVER_BIN;
207 bin_map[NEVER_BIN] = NEVER_BIN; 220 bin_map[NEVER_BIN] = NEVER_BIN;
208 } else if (global_state_.memory_limit_policy == ALLOW_ABSOLUTE_MINIMUM) { 221 } else if (global_state_.memory_limit_policy == ALLOW_ABSOLUTE_MINIMUM) {
(...skipping 84 matching lines...) Expand 10 before | Expand all | Expand 10 after
293 void TileManager::FreeResourcesForTile(Tile* tile) { 306 void TileManager::FreeResourcesForTile(Tile* tile) {
294 ManagedTileState& managed_tile_state = tile->managed_state(); 307 ManagedTileState& managed_tile_state = tile->managed_state();
295 DCHECK(managed_tile_state.can_be_freed); 308 DCHECK(managed_tile_state.can_be_freed);
296 if (managed_tile_state.resource_id) { 309 if (managed_tile_state.resource_id) {
297 resource_pool_->ReleaseResource(managed_tile_state.resource_id); 310 resource_pool_->ReleaseResource(managed_tile_state.resource_id);
298 managed_tile_state.resource_id = 0; 311 managed_tile_state.resource_id = 0;
299 } 312 }
300 } 313 }
301 314
302 void TileManager::DispatchMoreRasterTasks() { 315 void TileManager::DispatchMoreRasterTasks() {
303 while (!tiles_that_need_to_be_rasterized_.empty()) { 316 int max_pending_tasks = kNumPendingRasterTasksPerThread *
304 int max_pending_tasks = kNumPendingRasterTasksPerThread * 317 kMaxRasterThreads;
305 kMaxRasterThreads; 318 bool all_tiles_waiting_for_decoder = false;
306 319 while (!tiles_that_need_to_be_rasterized_.empty() &&
320 !all_tiles_waiting_for_decoder) {
307 // Stop dispatching raster tasks when too many are pending. 321 // Stop dispatching raster tasks when too many are pending.
308 if (pending_raster_tasks_ >= max_pending_tasks) 322 if (pending_raster_tasks_ >= max_pending_tasks)
309 break; 323 break;
310 324 all_tiles_waiting_for_decoder = true;
311 DispatchOneRasterTask(tiles_that_need_to_be_rasterized_.back()); 325 // TODO(qinmin): Use a separate queue for tiles that are doing image
312 tiles_that_need_to_be_rasterized_.pop_back(); 326 // decoding. However, we need to find a good way to keep track of
327 // the tile priority. Otherwise, one queue may starve the other queue.
328 TileVector::reverse_iterator it;
329 for (it = tiles_that_need_to_be_rasterized_.rbegin();
330 it != tiles_that_need_to_be_rasterized_.rend(); ++it) {
331 std::vector<SkPixelRef*> pixel_refs;
332 if (HasUndecodedImages(*it, pixel_refs)) {
333 if (pixel_refs.empty())
334 continue;
335 for (std::vector<SkPixelRef*>::iterator it = pixel_refs.begin();
336 it != pixel_refs.end(); ++it) {
337 SpawnImageDecodingTask(*it);
338 // If we are reaching the task limit, just finish here and wait for
339 // tasks to finish.
340 if (pending_raster_tasks_ >= max_pending_tasks)
341 return;
342 }
343 } else {
344 DispatchOneRasterTask(*it);
345 all_tiles_waiting_for_decoder = false;
346 // Be cautious that we are erasing a reverse iterator.
347 tiles_that_need_to_be_rasterized_.erase(--it.base());
348 break;
349 }
350 }
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
313 } 351 }
314 } 352 }
315 353
354 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
355 std::vector<SkPixelRef*>& unstarted) {
356 bool has_undecoded_images = false;
357 SkPixelRef* decode_not_started = 0;
358 ManagedTileState& managed_state = tile->managed_state();
359 for (std::vector<SkPixelRef*>::iterator it = managed_state.pixel_refs.begin();
360 it != managed_state.pixel_refs.end(); ++it) {
361 bool not_started = false;
362 switch(decoding_progress_[*it]) {
363 case FINISHED:
364 break;
365 case NOT_STARTED:
366 not_started = true;
367 case IN_PROGRESS:
368 scoped_refptr<Image> image(Image::Create(*it));
369 // If image is already in cache, don't spawn decode task.
370 if (!image->PrepareToDecode()) {
371 has_undecoded_images = true;
372 if (not_started)
373 unstarted.push_back(*it);
374 }
375 }
376 }
377 return has_undecoded_images;
378 }
379
380 void TileManager::SpawnImageDecodingTask(SkPixelRef* pixel_ref) {
381 TRACE_EVENT0("cc", "TileManager::SpawnImageDecodingTask");
382 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
383 // Kicking off a image decode job.
384 ++pending_raster_tasks_;
385 worker_pool_->GetTaskRunnerWithShutdownBehavior(
386 base::SequencedWorkerPool::SKIP_ON_SHUTDOWN)->PostTaskAndReply(
387 FROM_HERE,
388 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
389 image),
390 base::Bind(&TileManager::OnImageDecoded,
391 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
392 image));
393 decoding_progress_[pixel_ref] = IN_PROGRESS;
394 }
395
396 void TileManager::OnImageDecoded(scoped_refptr<Image> image) {
397 TRACE_EVENT0("cc", "TileManager::OnImageDecoded");
398 --pending_raster_tasks_;
399 decoding_progress_[image->pixel_ref()] = FINISHED;
400 DispatchMoreRasterTasks();
401 }
402
316 void TileManager::DispatchOneRasterTask(scoped_refptr<Tile> tile) { 403 void TileManager::DispatchOneRasterTask(scoped_refptr<Tile> tile) {
317 TRACE_EVENT0("cc", "TileManager::DispatchOneRasterTask"); 404 TRACE_EVENT0("cc", "TileManager::DispatchOneRasterTask");
318 scoped_refptr<PicturePileImpl> cloned_picture_pile = 405 scoped_refptr<PicturePileImpl> cloned_picture_pile =
319 tile->picture_pile()->CloneForDrawing(); 406 tile->picture_pile()->CloneForDrawing();
320 407
321 ManagedTileState& managed_tile_state = tile->managed_state(); 408 ManagedTileState& managed_tile_state = tile->managed_state();
322 DCHECK(managed_tile_state.can_use_gpu_memory); 409 DCHECK(managed_tile_state.can_use_gpu_memory);
323 ResourceProvider::ResourceId resource_id = 410 ResourceProvider::ResourceId resource_id =
324 resource_pool_->AcquireResource(tile->tile_size_.size(), tile->format_); 411 resource_pool_->AcquireResource(tile->tile_size_.size(), tile->format_);
325 resource_pool_->resource_provider()->acquirePixelBuffer(resource_id); 412 resource_pool_->resource_provider()->acquirePixelBuffer(resource_id);
(...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after
399 Tile* tile, ResourceProvider::ResourceId resource_id) { 486 Tile* tile, ResourceProvider::ResourceId resource_id) {
400 ManagedTileState& managed_tile_state = tile->managed_state(); 487 ManagedTileState& managed_tile_state = tile->managed_state();
401 DCHECK(!managed_tile_state.resource_id); 488 DCHECK(!managed_tile_state.resource_id);
402 managed_tile_state.resource_id = resource_id; 489 managed_tile_state.resource_id = resource_id;
403 managed_tile_state.resource_id_is_being_initialized = false; 490 managed_tile_state.resource_id_is_being_initialized = false;
404 // TODO(qinmin): Make this conditional on managed_tile_state.bin == NOW_BIN. 491 // TODO(qinmin): Make this conditional on managed_tile_state.bin == NOW_BIN.
405 client_->ScheduleRedraw(); 492 client_->ScheduleRedraw();
406 } 493 }
407 494
408 } 495 }
OLDNEW
« 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