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

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: Determine bin for each tree. 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) {
enne (OOO) 2012/12/16 01:26:44 This is a nice refactoring.
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 93 matching lines...) Expand 10 before | Expand all | Expand 10 after
137 check_for_completed_set_pixels_pending_(false) { 161 check_for_completed_set_pixels_pending_(false) {
138 // Initialize all threads. 162 // Initialize all threads.
139 const std::string thread_name_prefix = kRasterThreadNamePrefix; 163 const std::string thread_name_prefix = kRasterThreadNamePrefix;
140 while (raster_threads_.size() < num_raster_threads) { 164 while (raster_threads_.size() < num_raster_threads) {
141 int thread_number = raster_threads_.size() + 1; 165 int thread_number = raster_threads_.size() + 1;
142 scoped_ptr<RasterThread> thread = make_scoped_ptr( 166 scoped_ptr<RasterThread> thread = make_scoped_ptr(
143 new RasterThread(thread_name_prefix + 167 new RasterThread(thread_name_prefix +
144 StringPrintf("Worker%d", thread_number).c_str())); 168 StringPrintf("Worker%d", thread_number).c_str()));
145 raster_threads_.append(thread.Pass()); 169 raster_threads_.append(thread.Pass());
146 } 170 }
171
172 ResetBinCounts();
147 } 173 }
148 174
149 TileManager::~TileManager() { 175 TileManager::~TileManager() {
150 // Reset global state and manage. This should cause 176 // Reset global state and manage. This should cause
151 // our memory usage to drop to zero. 177 // our memory usage to drop to zero.
152 global_state_ = GlobalStateThatImpactsTilePriority(); 178 global_state_ = GlobalStateThatImpactsTilePriority();
153 AssignGpuMemoryToTiles(); 179 AssignGpuMemoryToTiles();
154 // This should finish all pending raster tasks and release any 180 // This should finish all pending raster tasks and release any
155 // uninitialized resources. 181 // uninitialized resources.
156 raster_threads_.clear(); 182 raster_threads_.clear();
(...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after
212 return; 238 return;
213 client_->ScheduleCheckForCompletedSetPixels(); 239 client_->ScheduleCheckForCompletedSetPixels();
214 check_for_completed_set_pixels_pending_ = true; 240 check_for_completed_set_pixels_pending_ = true;
215 } 241 }
216 242
217 class BinComparator { 243 class BinComparator {
218 public: 244 public:
219 bool operator() (const Tile* a, const Tile* b) const { 245 bool operator() (const Tile* a, const Tile* b) const {
220 const ManagedTileState& ams = a->managed_state(); 246 const ManagedTileState& ams = a->managed_state();
221 const ManagedTileState& bms = b->managed_state(); 247 const ManagedTileState& bms = b->managed_state();
222 if (ams.bin != bms.bin) 248 if (ams.raster_bin != bms.raster_bin)
223 return ams.bin < bms.bin; 249 return ams.raster_bin < bms.raster_bin;
224 250
225 if (ams.resolution != bms.resolution) 251 if (ams.resolution != bms.resolution)
226 return ams.resolution < ams.resolution; 252 return ams.resolution < ams.resolution;
227 253
228 return 254 return
229 ams.time_to_needed_in_seconds < 255 ams.time_to_needed_in_seconds <
230 bms.time_to_needed_in_seconds; 256 bms.time_to_needed_in_seconds;
231 } 257 }
232 }; 258 };
233 259
234 void TileManager::ManageTiles() { 260 void TileManager::ManageTiles() {
235 TRACE_EVENT0("cc", "TileManager::ManageTiles"); 261 TRACE_EVENT0("cc", "TileManager::ManageTiles");
236 manage_tiles_pending_ = false; 262 manage_tiles_pending_ = false;
237 263
238 // The amount of time for which we want to have prepainting coverage. 264 const bool smoothness_takes_priority =
239 const double prepainting_window_time_seconds = 1.0; 265 global_state_.smoothness_takes_priority;
240 const double backfling_guard_distance_pixels = 314.0;
241 266
242 const bool smoothness_takes_priority = global_state_.smoothness_takes_priority ; 267 // For each tree, bin into different categories of tiles.
243
244 // Bin into three categories of tiles: things we need now, things we need soon , and eventually
245 for (TileVector::iterator it = tiles_.begin(); it != tiles_.end(); ++it) { 268 for (TileVector::iterator it = tiles_.begin(); it != tiles_.end(); ++it) {
246 Tile* tile = *it; 269 Tile* tile = *it;
247 ManagedTileState& mts = tile->managed_state(); 270 ManagedTileState& mts = tile->managed_state();
271 mts.bin[ACTIVE_TREE] = BinFromTilePriority(tile->priority(ACTIVE_TREE));
272 mts.bin[PENDING_TREE] = BinFromTilePriority(tile->priority(PENDING_TREE));
273
248 TilePriority prio; 274 TilePriority prio;
249 if (smoothness_takes_priority) 275 if (smoothness_takes_priority)
250 prio = tile->priority(ACTIVE_TREE); 276 prio = tile->priority(ACTIVE_TREE);
251 else 277 else
252 prio = tile->combined_priority(); 278 prio = tile->combined_priority();
253 279
254 mts.resolution = prio.resolution; 280 mts.resolution = prio.resolution;
255 mts.time_to_needed_in_seconds = prio.time_to_needed_in_seconds(); 281 mts.time_to_needed_in_seconds = prio.time_to_needed_in_seconds();
256 282 mts.raster_bin = BinFromTilePriority(prio);
257 if (mts.time_to_needed_in_seconds ==
258 std::numeric_limits<float>::max()) {
259 mts.bin = NEVER_BIN;
260 continue;
261 }
262
263 if (mts.resolution == NON_IDEAL_RESOLUTION) {
264 mts.bin = EVENTUALLY_BIN;
265 continue;
266 }
267
268 if (mts.time_to_needed_in_seconds == 0 ||
269 prio.distance_to_visible_in_pixels < backfling_guard_distance_pixels) {
270 mts.bin = NOW_BIN;
271 continue;
272 }
273
274 if (prio.time_to_needed_in_seconds() < prepainting_window_time_seconds) {
275 mts.bin = SOON_BIN;
276 continue;
277 }
278
279 mts.bin = EVENTUALLY_BIN;
280 } 283 }
281 284
282 // Memory limit policy works by mapping some bin states to the NEVER bin. 285 // Memory limit policy works by mapping some bin states to the NEVER bin.
283 TileManagerBin bin_map[NUM_BINS]; 286 TileManagerBin bin_map[NUM_BINS];
284 if (global_state_.memory_limit_policy == ALLOW_NOTHING) { 287 if (global_state_.memory_limit_policy == ALLOW_NOTHING) {
285 bin_map[NOW_BIN] = NEVER_BIN; 288 bin_map[NOW_BIN] = NEVER_BIN;
286 bin_map[SOON_BIN] = NEVER_BIN; 289 bin_map[SOON_BIN] = NEVER_BIN;
287 bin_map[EVENTUALLY_BIN] = NEVER_BIN; 290 bin_map[EVENTUALLY_BIN] = NEVER_BIN;
288 bin_map[NEVER_BIN] = NEVER_BIN; 291 bin_map[NEVER_BIN] = NEVER_BIN;
289 } else if (global_state_.memory_limit_policy == ALLOW_ABSOLUTE_MINIMUM) { 292 } else if (global_state_.memory_limit_policy == ALLOW_ABSOLUTE_MINIMUM) {
290 bin_map[NOW_BIN] = NOW_BIN; 293 bin_map[NOW_BIN] = NOW_BIN;
291 bin_map[SOON_BIN] = NEVER_BIN; 294 bin_map[SOON_BIN] = NEVER_BIN;
292 bin_map[EVENTUALLY_BIN] = NEVER_BIN; 295 bin_map[EVENTUALLY_BIN] = NEVER_BIN;
293 bin_map[NEVER_BIN] = NEVER_BIN; 296 bin_map[NEVER_BIN] = NEVER_BIN;
294 } else if (global_state_.memory_limit_policy == ALLOW_PREPAINT_ONLY) { 297 } else if (global_state_.memory_limit_policy == ALLOW_PREPAINT_ONLY) {
295 bin_map[NOW_BIN] = NOW_BIN; 298 bin_map[NOW_BIN] = NOW_BIN;
296 bin_map[SOON_BIN] = SOON_BIN; 299 bin_map[SOON_BIN] = SOON_BIN;
297 bin_map[EVENTUALLY_BIN] = NEVER_BIN; 300 bin_map[EVENTUALLY_BIN] = NEVER_BIN;
298 bin_map[NEVER_BIN] = NEVER_BIN; 301 bin_map[NEVER_BIN] = NEVER_BIN;
299 } else { 302 } else {
300 bin_map[NOW_BIN] = NOW_BIN; 303 bin_map[NOW_BIN] = NOW_BIN;
301 bin_map[SOON_BIN] = SOON_BIN; 304 bin_map[SOON_BIN] = SOON_BIN;
302 bin_map[EVENTUALLY_BIN] = EVENTUALLY_BIN; 305 bin_map[EVENTUALLY_BIN] = EVENTUALLY_BIN;
303 bin_map[NEVER_BIN] = NEVER_BIN; 306 bin_map[NEVER_BIN] = NEVER_BIN;
304 } 307 }
305 for (TileVector::iterator it = tiles_.begin(); it != tiles_.end(); ++it) { 308 for (TileVector::iterator it = tiles_.begin(); it != tiles_.end(); ++it) {
306 Tile* tile = *it; 309 Tile* tile = *it;
307 TileManagerBin bin = bin_map[tile->managed_state().bin]; 310 ManagedTileState& mts = tile->managed_state();
308 tile->managed_state().bin = bin; 311 mts.bin[ACTIVE_TREE] = bin_map[mts.bin[ACTIVE_TREE]];
312 mts.bin[PENDING_TREE] = bin_map[mts.bin[PENDING_TREE]];
313 mts.raster_bin = bin_map[mts.raster_bin];
314 }
315
316 // Update bin counts.
317 ResetBinCounts();
318 for (TileVector::iterator it = tiles_.begin(); it != tiles_.end(); ++it) {
319 Tile* tile = *it;
320 ManagedTileState& mts = tile->managed_state();
321 for (int i = 0; i < NUM_TREES; ++i)
322 tiles_in_bin_count_[mts.bin[i]][i]++;
323
324 // Increment drawable count if GetResourceId() doesn't return 0.
325 if (tile->GetResourceId()) {
326 for (int i = 0; i < NUM_TREES; ++i)
327 drawable_tiles_in_bin_count_[mts.bin[i]][i]++;
328 }
309 } 329 }
310 330
311 // Sort by bin. 331 // Sort by bin.
312 std::sort(tiles_.begin(), tiles_.end(), BinComparator()); 332 std::sort(tiles_.begin(), tiles_.end(), BinComparator());
313 333
314 // Assign gpu memory and determine what tiles need to be rasterized. 334 // Assign gpu memory and determine what tiles need to be rasterized.
315 AssignGpuMemoryToTiles(); 335 AssignGpuMemoryToTiles();
316 336
317 // Finally, kick the rasterizer. 337 // Finally, kick the rasterizer.
318 DispatchMoreTasks(); 338 DispatchMoreTasks();
(...skipping 15 matching lines...) Expand all
334 354
335 // It's now safe to release the pixel buffer. 355 // It's now safe to release the pixel buffer.
336 resource_pool_->resource_provider()->releasePixelBuffer( 356 resource_pool_->resource_provider()->releasePixelBuffer(
337 tile->managed_state().resource->id()); 357 tile->managed_state().resource->id());
338 358
339 DidFinishTileInitialization(tile); 359 DidFinishTileInitialization(tile);
340 tiles_with_pending_set_pixels_.pop(); 360 tiles_with_pending_set_pixels_.pop();
341 } 361 }
342 } 362 }
343 363
344 void TileManager::renderingStats(RenderingStats* stats) { 364 void TileManager::GetRenderingStats(RenderingStats* stats) {
345 stats->totalRasterizeTimeInSeconds = 365 stats->totalRasterizeTimeInSeconds =
346 rendering_stats_.totalRasterizeTimeInSeconds; 366 rendering_stats_.totalRasterizeTimeInSeconds;
347 stats->totalPixelsRasterized = rendering_stats_.totalPixelsRasterized; 367 stats->totalPixelsRasterized = rendering_stats_.totalPixelsRasterized;
348 } 368 }
349 369
370 int TileManager::GetTilesInBinCount(TileManagerBin bin, WhichTree tree) {
371 DCHECK(bin >= 0);
372 DCHECK(bin < NUM_BINS);
373 DCHECK(tree >= 0);
374 DCHECK(tree < NUM_TREES);
375 return tiles_in_bin_count_[bin][tree];
376 }
377
378 int TileManager::GetDrawableTilesInBinCount(
379 TileManagerBin bin, WhichTree tree) {
380 DCHECK(bin >= 0);
381 DCHECK(bin < NUM_BINS);
382 DCHECK(tree >= 0);
383 DCHECK(tree < NUM_TREES);
384 return drawable_tiles_in_bin_count_[bin][tree];
385 }
386
387 void TileManager::ResetBinCounts() {
388 for (int i = 0; i < NUM_BINS; ++i)
389 for (int j = 0; j < NUM_TREES; ++j)
390 tiles_in_bin_count_[i][j] = drawable_tiles_in_bin_count_[i][j] = 0;
391 }
392
350 void TileManager::AssignGpuMemoryToTiles() { 393 void TileManager::AssignGpuMemoryToTiles() {
351 TRACE_EVENT0("cc", "TileManager::AssignGpuMemoryToTiles"); 394 TRACE_EVENT0("cc", "TileManager::AssignGpuMemoryToTiles");
352 // Some memory cannot be released. Figure out which. 395 // Some memory cannot be released. Figure out which.
353 size_t unreleasable_bytes = 0; 396 size_t unreleasable_bytes = 0;
354 for (TileVector::iterator it = tiles_.begin(); it != tiles_.end(); ++it) { 397 for (TileVector::iterator it = tiles_.begin(); it != tiles_.end(); ++it) {
355 Tile* tile = *it; 398 Tile* tile = *it;
356 if (!tile->managed_state().can_be_freed) 399 if (!tile->managed_state().can_be_freed)
357 unreleasable_bytes += tile->bytes_consumed_if_allocated(); 400 unreleasable_bytes += tile->bytes_consumed_if_allocated();
358 } 401 }
359 402
(...skipping 12 matching lines...) Expand all
372 } 415 }
373 tiles_with_image_decoding_tasks_.clear(); 416 tiles_with_image_decoding_tasks_.clear();
374 417
375 size_t bytes_left = global_state_.memory_limit_in_bytes - unreleasable_bytes; 418 size_t bytes_left = global_state_.memory_limit_in_bytes - unreleasable_bytes;
376 for (TileVector::iterator it = tiles_.begin(); it != tiles_.end(); ++it) { 419 for (TileVector::iterator it = tiles_.begin(); it != tiles_.end(); ++it) {
377 Tile* tile = *it; 420 Tile* tile = *it;
378 size_t tile_bytes = tile->bytes_consumed_if_allocated(); 421 size_t tile_bytes = tile->bytes_consumed_if_allocated();
379 ManagedTileState& managed_tile_state = tile->managed_state(); 422 ManagedTileState& managed_tile_state = tile->managed_state();
380 if (!managed_tile_state.can_be_freed) 423 if (!managed_tile_state.can_be_freed)
381 continue; 424 continue;
382 if (managed_tile_state.bin == NEVER_BIN) { 425 if (managed_tile_state.raster_bin == NEVER_BIN) {
383 managed_tile_state.can_use_gpu_memory = false; 426 managed_tile_state.can_use_gpu_memory = false;
384 FreeResourcesForTile(tile); 427 FreeResourcesForTile(tile);
385 continue; 428 continue;
386 } 429 }
387 if (tile_bytes > bytes_left) { 430 if (tile_bytes > bytes_left) {
388 managed_tile_state.can_use_gpu_memory = false; 431 managed_tile_state.can_use_gpu_memory = false;
389 FreeResourcesForTile(tile); 432 FreeResourcesForTile(tile);
390 continue; 433 continue;
391 } 434 }
392 bytes_left -= tile_bytes; 435 bytes_left -= tile_bytes;
(...skipping 219 matching lines...) Expand 10 before | Expand all | Expand 10 after
612 managed_tile_state.resource_is_being_initialized = false; 655 managed_tile_state.resource_is_being_initialized = false;
613 } 656 }
614 DispatchMoreTasks(); 657 DispatchMoreTasks();
615 } 658 }
616 659
617 void TileManager::DidFinishTileInitialization(Tile* tile) { 660 void TileManager::DidFinishTileInitialization(Tile* tile) {
618 ManagedTileState& managed_tile_state = tile->managed_state(); 661 ManagedTileState& managed_tile_state = tile->managed_state();
619 DCHECK(managed_tile_state.resource); 662 DCHECK(managed_tile_state.resource);
620 managed_tile_state.resource_is_being_initialized = false; 663 managed_tile_state.resource_is_being_initialized = false;
621 managed_tile_state.can_be_freed = true; 664 managed_tile_state.can_be_freed = true;
665 for (int i = 0; i < NUM_TREES; ++i)
666 drawable_tiles_in_bin_count_[managed_tile_state.bin[i]][i]++;
622 } 667 }
623 668
624 } 669 }
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