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

Side by Side Diff: cc/tile_manager.cc

Issue 11568027: cc: Add TileManager interface that allows LTHI to determine when to activate pending tree. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: rebase 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') | cc/tile_priority.h » ('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 #include <set>
9 9
10 #include "base/bind.h" 10 #include "base/bind.h"
(...skipping 13 matching lines...) Expand all
24 24
25 const char* kRasterThreadNamePrefix = "CompositorRaster"; 25 const char* kRasterThreadNamePrefix = "CompositorRaster";
26 26
27 const int kMaxRasterThreads = 64; 27 const int kMaxRasterThreads = 64;
28 const int kDefaultNumberOfRasterThreads = 1; 28 const int kDefaultNumberOfRasterThreads = 1;
29 29
30 // Allow two pending raster tasks per thread. This keeps resource usage 30 // Allow two pending raster tasks per thread. This keeps resource usage
31 // low while making sure raster threads aren't unnecessarily idle. 31 // low while making sure raster threads aren't unnecessarily idle.
32 const int kNumPendingRasterTasksPerThread = 2; 32 const int kNumPendingRasterTasksPerThread = 2;
33 33
34 // Determine bin based on three categories of tiles: things we need now,
35 // things we need soon, and eventually.
36 cc::TileManagerBin BinFromTilePriority(const cc::TilePriority& prio) {
37
38 // The amount of time for which we want to have prepainting coverage.
39 const double prepainting_window_time_seconds = 1.0;
40 const double backfling_guard_distance_pixels = 314.0;
41
42 if (prio.time_to_needed_in_seconds() == std::numeric_limits<float>::max())
43 return cc::NEVER_BIN;
44
45 if (prio.resolution == cc::NON_IDEAL_RESOLUTION)
46 return cc::EVENTUALLY_BIN;
47
48 if (prio.time_to_needed_in_seconds() == 0 ||
49 prio.distance_to_visible_in_pixels < backfling_guard_distance_pixels)
50 return cc::NOW_BIN;
51
52 if (prio.time_to_needed_in_seconds() < prepainting_window_time_seconds)
53 return cc::SOON_BIN;
54
55 return cc::EVENTUALLY_BIN;
56 }
57
34 } // namespace 58 } // namespace
35 59
36 namespace cc { 60 namespace cc {
37 61
38 class RasterThread : public base::Thread { 62 class RasterThread : public base::Thread {
39 public: 63 public:
40 RasterThread(const std::string name) 64 RasterThread(const std::string name)
41 : base::Thread(name.c_str()), 65 : base::Thread(name.c_str()),
42 num_pending_tasks_(0) { 66 num_pending_tasks_(0) {
43 Start(); 67 Start();
(...skipping 98 matching lines...) Expand 10 before | Expand all | Expand 10 after
142 check_for_completed_set_pixels_pending_(false) { 166 check_for_completed_set_pixels_pending_(false) {
143 // Initialize all threads. 167 // Initialize all threads.
144 const std::string thread_name_prefix = kRasterThreadNamePrefix; 168 const std::string thread_name_prefix = kRasterThreadNamePrefix;
145 while (raster_threads_.size() < num_raster_threads) { 169 while (raster_threads_.size() < num_raster_threads) {
146 int thread_number = raster_threads_.size() + 1; 170 int thread_number = raster_threads_.size() + 1;
147 scoped_ptr<RasterThread> thread = make_scoped_ptr( 171 scoped_ptr<RasterThread> thread = make_scoped_ptr(
148 new RasterThread(thread_name_prefix + 172 new RasterThread(thread_name_prefix +
149 StringPrintf("Worker%d", thread_number).c_str())); 173 StringPrintf("Worker%d", thread_number).c_str()));
150 raster_threads_.append(thread.Pass()); 174 raster_threads_.append(thread.Pass());
151 } 175 }
176
177 ResetBinCounts();
152 } 178 }
153 179
154 TileManager::~TileManager() { 180 TileManager::~TileManager() {
155 // Reset global state and manage. This should cause 181 // Reset global state and manage. This should cause
156 // our memory usage to drop to zero. 182 // our memory usage to drop to zero.
157 global_state_ = GlobalStateThatImpactsTilePriority(); 183 global_state_ = GlobalStateThatImpactsTilePriority();
158 AssignGpuMemoryToTiles(); 184 AssignGpuMemoryToTiles();
159 // This should finish all pending raster tasks and release any 185 // This should finish all pending raster tasks and release any
160 // uninitialized resources. 186 // uninitialized resources.
161 raster_threads_.clear(); 187 raster_threads_.clear();
(...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after
217 return; 243 return;
218 client_->ScheduleCheckForCompletedSetPixels(); 244 client_->ScheduleCheckForCompletedSetPixels();
219 check_for_completed_set_pixels_pending_ = true; 245 check_for_completed_set_pixels_pending_ = true;
220 } 246 }
221 247
222 class BinComparator { 248 class BinComparator {
223 public: 249 public:
224 bool operator() (const Tile* a, const Tile* b) const { 250 bool operator() (const Tile* a, const Tile* b) const {
225 const ManagedTileState& ams = a->managed_state(); 251 const ManagedTileState& ams = a->managed_state();
226 const ManagedTileState& bms = b->managed_state(); 252 const ManagedTileState& bms = b->managed_state();
227 if (ams.bin != bms.bin) 253 if (ams.raster_bin != bms.raster_bin)
228 return ams.bin < bms.bin; 254 return ams.raster_bin < bms.raster_bin;
229 255
230 if (ams.resolution != bms.resolution) 256 if (ams.resolution != bms.resolution)
231 return ams.resolution < ams.resolution; 257 return ams.resolution < ams.resolution;
232 258
233 return 259 return
234 ams.time_to_needed_in_seconds < 260 ams.time_to_needed_in_seconds <
235 bms.time_to_needed_in_seconds; 261 bms.time_to_needed_in_seconds;
236 } 262 }
237 }; 263 };
238 264
239 void TileManager::ManageTiles() { 265 void TileManager::ManageTiles() {
240 TRACE_EVENT0("cc", "TileManager::ManageTiles"); 266 TRACE_EVENT0("cc", "TileManager::ManageTiles");
241 manage_tiles_pending_ = false; 267 manage_tiles_pending_ = false;
242 ++manage_tiles_call_count_; 268 ++manage_tiles_call_count_;
243 269
244 // The amount of time for which we want to have prepainting coverage. 270 const bool smoothness_takes_priority =
245 const double prepainting_window_time_seconds = 1.0; 271 global_state_.smoothness_takes_priority;
246 const double backfling_guard_distance_pixels = 314.0;
247 272
248 const bool smoothness_takes_priority = global_state_.smoothness_takes_priority ; 273 // For each tree, bin into different categories of tiles.
249
250 // Bin into three categories of tiles: things we need now, things we need soon , and eventually
251 for (TileVector::iterator it = tiles_.begin(); it != tiles_.end(); ++it) { 274 for (TileVector::iterator it = tiles_.begin(); it != tiles_.end(); ++it) {
252 Tile* tile = *it; 275 Tile* tile = *it;
253 ManagedTileState& mts = tile->managed_state(); 276 ManagedTileState& mts = tile->managed_state();
277 mts.bin[ACTIVE_TREE] = BinFromTilePriority(tile->priority(ACTIVE_TREE));
278 mts.bin[PENDING_TREE] = BinFromTilePriority(tile->priority(PENDING_TREE));
279
254 TilePriority prio; 280 TilePriority prio;
255 if (smoothness_takes_priority) 281 if (smoothness_takes_priority)
256 prio = tile->priority(ACTIVE_TREE); 282 prio = tile->priority(ACTIVE_TREE);
257 else 283 else
258 prio = tile->combined_priority(); 284 prio = tile->combined_priority();
259 285
260 mts.resolution = prio.resolution; 286 mts.resolution = prio.resolution;
261 mts.time_to_needed_in_seconds = prio.time_to_needed_in_seconds(); 287 mts.time_to_needed_in_seconds = prio.time_to_needed_in_seconds();
262 288 mts.raster_bin = BinFromTilePriority(prio);
263 if (mts.time_to_needed_in_seconds ==
264 std::numeric_limits<float>::max()) {
265 mts.bin = NEVER_BIN;
266 continue;
267 }
268
269 if (mts.resolution == NON_IDEAL_RESOLUTION) {
270 mts.bin = EVENTUALLY_BIN;
271 continue;
272 }
273
274 if (mts.time_to_needed_in_seconds == 0 ||
275 prio.distance_to_visible_in_pixels < backfling_guard_distance_pixels) {
276 mts.bin = NOW_BIN;
277 continue;
278 }
279
280 if (prio.time_to_needed_in_seconds() < prepainting_window_time_seconds) {
281 mts.bin = SOON_BIN;
282 continue;
283 }
284
285 mts.bin = EVENTUALLY_BIN;
286 } 289 }
287 290
288 // Memory limit policy works by mapping some bin states to the NEVER bin. 291 // Memory limit policy works by mapping some bin states to the NEVER bin.
289 TileManagerBin bin_map[NUM_BINS]; 292 TileManagerBin bin_map[NUM_BINS];
290 if (global_state_.memory_limit_policy == ALLOW_NOTHING) { 293 if (global_state_.memory_limit_policy == ALLOW_NOTHING) {
291 bin_map[NOW_BIN] = NEVER_BIN; 294 bin_map[NOW_BIN] = NEVER_BIN;
292 bin_map[SOON_BIN] = NEVER_BIN; 295 bin_map[SOON_BIN] = NEVER_BIN;
293 bin_map[EVENTUALLY_BIN] = NEVER_BIN; 296 bin_map[EVENTUALLY_BIN] = NEVER_BIN;
294 bin_map[NEVER_BIN] = NEVER_BIN; 297 bin_map[NEVER_BIN] = NEVER_BIN;
295 } else if (global_state_.memory_limit_policy == ALLOW_ABSOLUTE_MINIMUM) { 298 } else if (global_state_.memory_limit_policy == ALLOW_ABSOLUTE_MINIMUM) {
296 bin_map[NOW_BIN] = NOW_BIN; 299 bin_map[NOW_BIN] = NOW_BIN;
297 bin_map[SOON_BIN] = NEVER_BIN; 300 bin_map[SOON_BIN] = NEVER_BIN;
298 bin_map[EVENTUALLY_BIN] = NEVER_BIN; 301 bin_map[EVENTUALLY_BIN] = NEVER_BIN;
299 bin_map[NEVER_BIN] = NEVER_BIN; 302 bin_map[NEVER_BIN] = NEVER_BIN;
300 } else if (global_state_.memory_limit_policy == ALLOW_PREPAINT_ONLY) { 303 } else if (global_state_.memory_limit_policy == ALLOW_PREPAINT_ONLY) {
301 bin_map[NOW_BIN] = NOW_BIN; 304 bin_map[NOW_BIN] = NOW_BIN;
302 bin_map[SOON_BIN] = SOON_BIN; 305 bin_map[SOON_BIN] = SOON_BIN;
303 bin_map[EVENTUALLY_BIN] = NEVER_BIN; 306 bin_map[EVENTUALLY_BIN] = NEVER_BIN;
304 bin_map[NEVER_BIN] = NEVER_BIN; 307 bin_map[NEVER_BIN] = NEVER_BIN;
305 } else { 308 } else {
306 bin_map[NOW_BIN] = NOW_BIN; 309 bin_map[NOW_BIN] = NOW_BIN;
307 bin_map[SOON_BIN] = SOON_BIN; 310 bin_map[SOON_BIN] = SOON_BIN;
308 bin_map[EVENTUALLY_BIN] = EVENTUALLY_BIN; 311 bin_map[EVENTUALLY_BIN] = EVENTUALLY_BIN;
309 bin_map[NEVER_BIN] = NEVER_BIN; 312 bin_map[NEVER_BIN] = NEVER_BIN;
310 } 313 }
311 for (TileVector::iterator it = tiles_.begin(); it != tiles_.end(); ++it) { 314 for (TileVector::iterator it = tiles_.begin(); it != tiles_.end(); ++it) {
312 Tile* tile = *it; 315 Tile* tile = *it;
313 TileManagerBin bin = bin_map[tile->managed_state().bin]; 316 ManagedTileState& mts = tile->managed_state();
314 tile->managed_state().bin = bin; 317 mts.bin[ACTIVE_TREE] = bin_map[mts.bin[ACTIVE_TREE]];
318 mts.bin[PENDING_TREE] = bin_map[mts.bin[PENDING_TREE]];
319 mts.raster_bin = bin_map[mts.raster_bin];
320 }
321
322 // Update bin counts.
323 ResetBinCounts();
324 for (TileVector::iterator it = tiles_.begin(); it != tiles_.end(); ++it) {
325 Tile* tile = *it;
326 ManagedTileState& mts = tile->managed_state();
327 for (int i = 0; i < NUM_TREES; ++i)
328 tiles_in_bin_count_[mts.bin[i]][i]++;
329
330 // Increment drawable count if GetResourceId() doesn't return 0.
331 if (tile->GetResourceId()) {
332 for (int i = 0; i < NUM_TREES; ++i)
333 drawable_tiles_in_bin_count_[mts.bin[i]][i]++;
334 }
315 } 335 }
316 336
317 // Sort by bin. 337 // Sort by bin.
318 std::sort(tiles_.begin(), tiles_.end(), BinComparator()); 338 std::sort(tiles_.begin(), tiles_.end(), BinComparator());
319 339
320 // Assign gpu memory and determine what tiles need to be rasterized. 340 // Assign gpu memory and determine what tiles need to be rasterized.
321 AssignGpuMemoryToTiles(); 341 AssignGpuMemoryToTiles();
322 342
323 // Finally, kick the rasterizer. 343 // Finally, kick the rasterizer.
324 DispatchMoreTasks(); 344 DispatchMoreTasks();
(...skipping 15 matching lines...) Expand all
340 360
341 // It's now safe to release the pixel buffer. 361 // It's now safe to release the pixel buffer.
342 resource_pool_->resource_provider()->releasePixelBuffer( 362 resource_pool_->resource_provider()->releasePixelBuffer(
343 tile->managed_state().resource->id()); 363 tile->managed_state().resource->id());
344 364
345 DidFinishTileInitialization(tile); 365 DidFinishTileInitialization(tile);
346 tiles_with_pending_set_pixels_.pop(); 366 tiles_with_pending_set_pixels_.pop();
347 } 367 }
348 } 368 }
349 369
350 void TileManager::renderingStats(RenderingStats* stats) { 370 void TileManager::GetRenderingStats(RenderingStats* stats) {
351 stats->totalRasterizeTimeInSeconds = 371 stats->totalRasterizeTimeInSeconds =
352 rendering_stats_.totalRasterizeTimeInSeconds; 372 rendering_stats_.totalRasterizeTimeInSeconds;
353 stats->totalPixelsRasterized = rendering_stats_.totalPixelsRasterized; 373 stats->totalPixelsRasterized = rendering_stats_.totalPixelsRasterized;
354 stats->totalDeferredImageDecodeCount = 374 stats->totalDeferredImageDecodeCount =
355 rendering_stats_.totalDeferredImageDecodeCount; 375 rendering_stats_.totalDeferredImageDecodeCount;
356 stats->totalDeferredImageCacheHitCount = 376 stats->totalDeferredImageCacheHitCount =
357 rendering_stats_.totalDeferredImageCacheHitCount; 377 rendering_stats_.totalDeferredImageCacheHitCount;
358 stats->totalImageGatheringCount = rendering_stats_.totalImageGatheringCount; 378 stats->totalImageGatheringCount = rendering_stats_.totalImageGatheringCount;
359 stats->totalDeferredImageDecodeTimeInSeconds = 379 stats->totalDeferredImageDecodeTimeInSeconds =
360 rendering_stats_.totalDeferredImageDecodeTimeInSeconds; 380 rendering_stats_.totalDeferredImageDecodeTimeInSeconds;
361 stats->totalImageGatheringTimeInSeconds = 381 stats->totalImageGatheringTimeInSeconds =
362 rendering_stats_.totalImageGatheringTimeInSeconds; 382 rendering_stats_.totalImageGatheringTimeInSeconds;
363 } 383 }
364 384
385 int TileManager::GetTilesInBinCount(TileManagerBin bin, WhichTree tree) {
386 DCHECK(bin >= 0);
387 DCHECK(bin < NUM_BINS);
388 DCHECK(tree >= 0);
389 DCHECK(tree < NUM_TREES);
390 return tiles_in_bin_count_[bin][tree];
391 }
392
393 int TileManager::GetDrawableTilesInBinCount(
394 TileManagerBin bin, WhichTree tree) {
395 DCHECK(bin >= 0);
396 DCHECK(bin < NUM_BINS);
397 DCHECK(tree >= 0);
398 DCHECK(tree < NUM_TREES);
399 return drawable_tiles_in_bin_count_[bin][tree];
400 }
401
402 void TileManager::ResetBinCounts() {
403 for (int i = 0; i < NUM_BINS; ++i)
404 for (int j = 0; j < NUM_TREES; ++j)
405 tiles_in_bin_count_[i][j] = drawable_tiles_in_bin_count_[i][j] = 0;
406 }
407
365 void TileManager::AssignGpuMemoryToTiles() { 408 void TileManager::AssignGpuMemoryToTiles() {
366 TRACE_EVENT0("cc", "TileManager::AssignGpuMemoryToTiles"); 409 TRACE_EVENT0("cc", "TileManager::AssignGpuMemoryToTiles");
367 // Some memory cannot be released. Figure out which. 410 // Some memory cannot be released. Figure out which.
368 size_t unreleasable_bytes = 0; 411 size_t unreleasable_bytes = 0;
369 for (TileVector::iterator it = tiles_.begin(); it != tiles_.end(); ++it) { 412 for (TileVector::iterator it = tiles_.begin(); it != tiles_.end(); ++it) {
370 Tile* tile = *it; 413 Tile* tile = *it;
371 if (!tile->managed_state().can_be_freed) 414 if (!tile->managed_state().can_be_freed)
372 unreleasable_bytes += tile->bytes_consumed_if_allocated(); 415 unreleasable_bytes += tile->bytes_consumed_if_allocated();
373 } 416 }
374 417
375 // Now give memory out to the tiles until we're out, and build 418 // Now give memory out to the tiles until we're out, and build
376 // the needs-to-be-rasterized queue. 419 // the needs-to-be-rasterized queue.
377 tiles_that_need_to_be_rasterized_.erase( 420 tiles_that_need_to_be_rasterized_.erase(
378 tiles_that_need_to_be_rasterized_.begin(), 421 tiles_that_need_to_be_rasterized_.begin(),
379 tiles_that_need_to_be_rasterized_.end()); 422 tiles_that_need_to_be_rasterized_.end());
380 423
381 // Reset the image decoding list so that we don't mess up with tile 424 // Reset the image decoding list so that we don't mess up with tile
382 // priorities. Tiles will be added to the image decoding list again 425 // priorities. Tiles will be added to the image decoding list again
383 // when DispatchMoreTasks() is called. 426 // when DispatchMoreTasks() is called.
384 tiles_with_image_decoding_tasks_.clear(); 427 tiles_with_image_decoding_tasks_.clear();
385 428
386 size_t bytes_left = global_state_.memory_limit_in_bytes - unreleasable_bytes; 429 size_t bytes_left = global_state_.memory_limit_in_bytes - unreleasable_bytes;
387 for (TileVector::iterator it = tiles_.begin(); it != tiles_.end(); ++it) { 430 for (TileVector::iterator it = tiles_.begin(); it != tiles_.end(); ++it) {
388 Tile* tile = *it; 431 Tile* tile = *it;
389 size_t tile_bytes = tile->bytes_consumed_if_allocated(); 432 size_t tile_bytes = tile->bytes_consumed_if_allocated();
390 ManagedTileState& managed_tile_state = tile->managed_state(); 433 ManagedTileState& managed_tile_state = tile->managed_state();
391 if (!managed_tile_state.can_be_freed) 434 if (!managed_tile_state.can_be_freed)
392 continue; 435 continue;
393 if (managed_tile_state.bin == NEVER_BIN) { 436 if (managed_tile_state.raster_bin == NEVER_BIN) {
394 managed_tile_state.can_use_gpu_memory = false; 437 managed_tile_state.can_use_gpu_memory = false;
395 FreeResourcesForTile(tile); 438 FreeResourcesForTile(tile);
396 continue; 439 continue;
397 } 440 }
398 if (tile_bytes > bytes_left) { 441 if (tile_bytes > bytes_left) {
399 managed_tile_state.can_use_gpu_memory = false; 442 managed_tile_state.can_use_gpu_memory = false;
400 FreeResourcesForTile(tile); 443 FreeResourcesForTile(tile);
401 continue; 444 continue;
402 } 445 }
403 bytes_left -= tile_bytes; 446 bytes_left -= tile_bytes;
(...skipping 233 matching lines...) Expand 10 before | Expand all | Expand 10 after
637 managed_tile_state.resource_is_being_initialized = false; 680 managed_tile_state.resource_is_being_initialized = false;
638 } 681 }
639 DispatchMoreTasks(); 682 DispatchMoreTasks();
640 } 683 }
641 684
642 void TileManager::DidFinishTileInitialization(Tile* tile) { 685 void TileManager::DidFinishTileInitialization(Tile* tile) {
643 ManagedTileState& managed_tile_state = tile->managed_state(); 686 ManagedTileState& managed_tile_state = tile->managed_state();
644 DCHECK(managed_tile_state.resource); 687 DCHECK(managed_tile_state.resource);
645 managed_tile_state.resource_is_being_initialized = false; 688 managed_tile_state.resource_is_being_initialized = false;
646 managed_tile_state.can_be_freed = true; 689 managed_tile_state.can_be_freed = true;
690 for (int i = 0; i < NUM_TREES; ++i)
691 drawable_tiles_in_bin_count_[managed_tile_state.bin[i]][i]++;
647 } 692 }
648 693
649 } 694 }
OLDNEW
« no previous file with comments | « cc/tile_manager.h ('k') | cc/tile_priority.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698