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

Side by Side Diff: cc/resources/picture_layer_tiling.cc

Issue 140513006: cc: Simplify picture layer tiling update tile priorities. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Created 6 years, 10 months 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/resources/picture_layer_tiling.h" 5 #include "cc/resources/picture_layer_tiling.h"
6 6
7 #include <algorithm> 7 #include <algorithm>
8 #include <cmath> 8 #include <cmath>
9 #include <limits> 9 #include <limits>
10 10
(...skipping 321 matching lines...) Expand 10 before | Expand all | Expand 10 after
332 332
333 gfx::Size PictureLayerTiling::CoverageIterator::texture_size() const { 333 gfx::Size PictureLayerTiling::CoverageIterator::texture_size() const {
334 return tiling_->tiling_data_.max_texture_size(); 334 return tiling_->tiling_data_.max_texture_size();
335 } 335 }
336 336
337 void PictureLayerTiling::Reset() { 337 void PictureLayerTiling::Reset() {
338 live_tiles_rect_ = gfx::Rect(); 338 live_tiles_rect_ = gfx::Rect();
339 tiles_.clear(); 339 tiles_.clear();
340 } 340 }
341 341
342 gfx::Rect PictureLayerTiling::ComputeSkewport(
epennerAtGoogle 2014/02/03 23:43:03 This could benefit from a high-level comment descr
vmpstr 2014/02/04 19:50:49 I added a comment in the header file.
343 double current_frame_time_in_seconds,
344 const gfx::Rect& visible_rect_in_content_space) const {
345 gfx::Rect skewport = visible_rect_in_content_space;
346 if (last_impl_frame_time_in_seconds_ == 0.0)
347 return skewport;
348
349 double time_delta =
350 current_frame_time_in_seconds - last_impl_frame_time_in_seconds_;
351 if (time_delta == 0.0)
352 return skewport;
353
354 float skewport_target_time_in_seconds =
355 client_->GetSkewportTargetTimeInSeconds();
356 double extrapolation_multiplier =
357 skewport_target_time_in_seconds / time_delta;
358
359 int old_width = last_visible_rect_in_content_space_.width();
360 int old_height = last_visible_rect_in_content_space_.height();
361 int old_x = last_visible_rect_in_content_space_.x();
362 int old_y = last_visible_rect_in_content_space_.y();
363
364 int new_width = visible_rect_in_content_space.width();
365 int new_height = visible_rect_in_content_space.height();
366 int new_x = visible_rect_in_content_space.x();
367 int new_y = visible_rect_in_content_space.y();
368
369 skewport.set_width(skewport.width() +
370 extrapolation_multiplier * (new_width - old_width));
371 skewport.set_height(skewport.height() +
372 extrapolation_multiplier * (new_height - old_height));
373 skewport.set_x(skewport.x() + extrapolation_multiplier * (new_x - old_x));
374 skewport.set_y(skewport.y() + extrapolation_multiplier * (new_y - old_y));
375 skewport.Union(visible_rect_in_content_space);
376 return skewport;
377 }
378
342 void PictureLayerTiling::UpdateTilePriorities( 379 void PictureLayerTiling::UpdateTilePriorities(
343 WhichTree tree, 380 WhichTree tree,
344 const gfx::Size& device_viewport,
345 const gfx::Rect& viewport_in_layer_space,
346 const gfx::Rect& visible_layer_rect, 381 const gfx::Rect& visible_layer_rect,
347 const gfx::Size& last_layer_bounds, 382 float layer_contents_scale,
348 const gfx::Size& current_layer_bounds, 383 double current_frame_time_in_seconds) {
349 float last_layer_contents_scale,
350 float current_layer_contents_scale,
351 const gfx::Transform& last_screen_transform,
352 const gfx::Transform& current_screen_transform,
353 double current_frame_time_in_seconds,
354 size_t max_tiles_for_interest_area) {
355 if (!NeedsUpdateForFrameAtTime(current_frame_time_in_seconds)) { 384 if (!NeedsUpdateForFrameAtTime(current_frame_time_in_seconds)) {
356 // This should never be zero for the purposes of has_ever_been_updated(). 385 // This should never be zero for the purposes of has_ever_been_updated().
357 DCHECK_NE(current_frame_time_in_seconds, 0.0); 386 DCHECK_NE(current_frame_time_in_seconds, 0.0);
358 return; 387 return;
359 } 388 }
389
390 gfx::Rect visible_rect_in_content_space =
391 gfx::ScaleToEnclosingRect(visible_layer_rect, contents_scale_);
392
360 if (ContentRect().IsEmpty()) { 393 if (ContentRect().IsEmpty()) {
361 last_impl_frame_time_in_seconds_ = current_frame_time_in_seconds; 394 last_impl_frame_time_in_seconds_ = current_frame_time_in_seconds;
395 last_visible_rect_in_content_space_ = visible_rect_in_content_space;
362 return; 396 return;
363 } 397 }
364 398
365 gfx::Rect viewport_in_content_space = 399 size_t max_tiles_for_interest_area = client_->GetMaxTilesForInterestArea();
366 gfx::ScaleToEnclosingRect(viewport_in_layer_space, contents_scale_);
367 gfx::Rect visible_content_rect =
368 gfx::ScaleToEnclosingRect(visible_layer_rect, contents_scale_);
369 400
370 gfx::Size tile_size = tiling_data_.max_texture_size(); 401 gfx::Size tile_size = tiling_data_.max_texture_size();
371 int64 interest_rect_area = 402 int64 eventually_rect_area =
372 max_tiles_for_interest_area * tile_size.width() * tile_size.height(); 403 max_tiles_for_interest_area * tile_size.width() * tile_size.height();
373 404
374 gfx::Rect starting_rect = visible_content_rect.IsEmpty() 405 gfx::Rect skewport = ComputeSkewport(current_frame_time_in_seconds,
375 ? viewport_in_content_space 406 visible_rect_in_content_space);
376 : visible_content_rect; 407 DCHECK(skewport.Contains(visible_rect_in_content_space));
377 gfx::Rect interest_rect = ExpandRectEquallyToAreaBoundedBy(
378 starting_rect,
379 interest_rect_area,
380 ContentRect(),
381 &expansion_cache_);
382 DCHECK(interest_rect.IsEmpty() ||
383 ContentRect().Contains(interest_rect));
384 408
385 SetLiveTilesRect(interest_rect); 409 gfx::Rect eventually_rect =
410 ExpandRectEquallyToAreaBoundedBy(visible_rect_in_content_space,
411 eventually_rect_area,
412 ContentRect(),
413 &expansion_cache_);
414 DCHECK(eventually_rect.IsEmpty() ||
415 ContentRect().Contains(eventually_rect));
386 416
387 double time_delta = 0; 417 SetLiveTilesRect(eventually_rect);
388 if (last_impl_frame_time_in_seconds_ != 0.0 && 418
389 last_layer_bounds == current_layer_bounds) { 419 last_impl_frame_time_in_seconds_ = current_frame_time_in_seconds;
390 time_delta = 420 last_visible_rect_in_content_space_ = visible_rect_in_content_space;
391 current_frame_time_in_seconds - last_impl_frame_time_in_seconds_; 421
422 // Assign now priority to all visible tiles.
423 TilePriority now_priority(resolution_, TilePriority::NOW, 0);
424 for (TilingData::Iterator iter(&tiling_data_, visible_rect_in_content_space);
425 iter;
426 ++iter) {
427 TileMap::iterator find = tiles_.find(iter.index());
428 if (find == tiles_.end())
429 continue;
430 Tile* tile = find->second.get();
431
432 tile->SetPriority(tree, now_priority);
392 } 433 }
393 434
394 gfx::RectF view_rect(device_viewport); 435 // Assign soon priority to all tiles in the skewport that are not visible.
395 float current_scale = current_layer_contents_scale / contents_scale_; 436 float content_to_screen_scale =
396 float last_scale = last_layer_contents_scale / contents_scale_; 437 1.0f / (contents_scale_ * layer_contents_scale);
438 for (TilingData::DifferenceIterator iter(
439 &tiling_data_, skewport, visible_rect_in_content_space);
440 iter;
441 ++iter) {
442 TileMap::iterator find = tiles_.find(iter.index());
443 if (find == tiles_.end())
444 continue;
445 Tile* tile = find->second.get();
397 446
398 // Fast path tile priority calculation when both transforms are translations. 447 gfx::Rect tile_bounds =
399 if (last_screen_transform.IsApproximatelyIdentityOrTranslation( 448 tiling_data_.TileBounds(iter.index_x(), iter.index_y());
400 std::numeric_limits<float>::epsilon()) &&
401 current_screen_transform.IsApproximatelyIdentityOrTranslation(
402 std::numeric_limits<float>::epsilon())) {
403 gfx::Vector2dF current_offset(
404 current_screen_transform.matrix().get(0, 3),
405 current_screen_transform.matrix().get(1, 3));
406 gfx::Vector2dF last_offset(
407 last_screen_transform.matrix().get(0, 3),
408 last_screen_transform.matrix().get(1, 3));
409 449
410 for (TilingData::Iterator iter(&tiling_data_, interest_rect); 450 float distance_to_visible =
411 iter; ++iter) { 451 visible_rect_in_content_space.ManhattanInternalDistance(tile_bounds) *
412 TileMap::iterator find = tiles_.find(iter.index()); 452 content_to_screen_scale;
413 if (find == tiles_.end())
414 continue;
415 Tile* tile = find->second.get();
416 453
417 gfx::Rect tile_bounds = 454 TilePriority priority(
418 tiling_data_.TileBounds(iter.index_x(), iter.index_y()); 455 resolution_, TilePriority::SOON, distance_to_visible);
419 gfx::RectF current_screen_rect = gfx::ScaleRect( 456 tile->SetPriority(tree, priority);
420 tile_bounds,
421 current_scale,
422 current_scale) + current_offset;
423 gfx::RectF last_screen_rect = gfx::ScaleRect(
424 tile_bounds,
425 last_scale,
426 last_scale) + last_offset;
427
428 float distance_to_visible_in_pixels =
429 current_screen_rect.ManhattanInternalDistance(view_rect);
430
431 float time_to_visible_in_seconds =
432 TilePriority::TimeForBoundsToIntersect(
433 last_screen_rect, current_screen_rect, time_delta, view_rect);
434 TilePriority priority(
435 resolution_,
436 time_to_visible_in_seconds,
437 distance_to_visible_in_pixels);
438 tile->SetPriority(tree, priority);
439 }
440 } else if (!last_screen_transform.HasPerspective() &&
441 !current_screen_transform.HasPerspective()) {
442 // Secondary fast path that can be applied for any affine transforms.
443
444 // Initialize the necessary geometry in screen space, so that we can
445 // iterate over tiles in screen space without needing a costly transform
446 // mapping for each tile.
447
448 // Apply screen space transform to the local origin point (0, 0); only the
449 // translation component is needed and can be initialized directly.
450 gfx::Point current_screen_space_origin(
451 current_screen_transform.matrix().get(0, 3),
452 current_screen_transform.matrix().get(1, 3));
453
454 gfx::Point last_screen_space_origin(
455 last_screen_transform.matrix().get(0, 3),
456 last_screen_transform.matrix().get(1, 3));
457
458 float current_tile_width = tiling_data_.TileSizeX(0) * current_scale;
459 float last_tile_width = tiling_data_.TileSizeX(0) * last_scale;
460 float current_tile_height = tiling_data_.TileSizeY(0) * current_scale;
461 float last_tile_height = tiling_data_.TileSizeY(0) * last_scale;
462
463 // Apply screen space transform to local basis vectors (tile_width, 0) and
464 // (0, tile_height); the math simplifies and can be initialized directly.
465 gfx::Vector2dF current_horizontal(
466 current_screen_transform.matrix().get(0, 0) * current_tile_width,
467 current_screen_transform.matrix().get(1, 0) * current_tile_width);
468 gfx::Vector2dF current_vertical(
469 current_screen_transform.matrix().get(0, 1) * current_tile_height,
470 current_screen_transform.matrix().get(1, 1) * current_tile_height);
471
472 gfx::Vector2dF last_horizontal(
473 last_screen_transform.matrix().get(0, 0) * last_tile_width,
474 last_screen_transform.matrix().get(1, 0) * last_tile_width);
475 gfx::Vector2dF last_vertical(
476 last_screen_transform.matrix().get(0, 1) * last_tile_height,
477 last_screen_transform.matrix().get(1, 1) * last_tile_height);
478
479 for (TilingData::Iterator iter(&tiling_data_, interest_rect);
480 iter; ++iter) {
481 TileMap::iterator find = tiles_.find(iter.index());
482 if (find == tiles_.end())
483 continue;
484
485 Tile* tile = find->second.get();
486
487 int i = iter.index_x();
488 int j = iter.index_y();
489 gfx::PointF current_tile_origin = current_screen_space_origin +
490 ScaleVector2d(current_horizontal, i) +
491 ScaleVector2d(current_vertical, j);
492 gfx::PointF last_tile_origin = last_screen_space_origin +
493 ScaleVector2d(last_horizontal, i) +
494 ScaleVector2d(last_vertical, j);
495
496 gfx::RectF current_screen_rect = gfx::QuadF(
497 current_tile_origin,
498 current_tile_origin + current_horizontal,
499 current_tile_origin + current_horizontal + current_vertical,
500 current_tile_origin + current_vertical).BoundingBox();
501
502 gfx::RectF last_screen_rect = gfx::QuadF(
503 last_tile_origin,
504 last_tile_origin + last_horizontal,
505 last_tile_origin + last_horizontal + last_vertical,
506 last_tile_origin + last_vertical).BoundingBox();
507
508 float distance_to_visible_in_pixels =
509 current_screen_rect.ManhattanInternalDistance(view_rect);
510
511 float time_to_visible_in_seconds =
512 TilePriority::TimeForBoundsToIntersect(
513 last_screen_rect, current_screen_rect, time_delta, view_rect);
514 TilePriority priority(
515 resolution_,
516 time_to_visible_in_seconds,
517 distance_to_visible_in_pixels);
518 tile->SetPriority(tree, priority);
519 }
520 } else {
521 for (TilingData::Iterator iter(&tiling_data_, interest_rect);
522 iter; ++iter) {
523 TileMap::iterator find = tiles_.find(iter.index());
524 if (find == tiles_.end())
525 continue;
526 Tile* tile = find->second.get();
527
528 gfx::Rect tile_bounds =
529 tiling_data_.TileBounds(iter.index_x(), iter.index_y());
530 gfx::RectF current_layer_content_rect = gfx::ScaleRect(
531 tile_bounds,
532 current_scale,
533 current_scale);
534 gfx::RectF current_screen_rect = MathUtil::MapClippedRect(
535 current_screen_transform, current_layer_content_rect);
536 gfx::RectF last_layer_content_rect = gfx::ScaleRect(
537 tile_bounds,
538 last_scale,
539 last_scale);
540 gfx::RectF last_screen_rect = MathUtil::MapClippedRect(
541 last_screen_transform, last_layer_content_rect);
542
543 float distance_to_visible_in_pixels =
544 current_screen_rect.ManhattanInternalDistance(view_rect);
545
546 float time_to_visible_in_seconds =
547 TilePriority::TimeForBoundsToIntersect(
548 last_screen_rect, current_screen_rect, time_delta, view_rect);
549
550 TilePriority priority(
551 resolution_,
552 time_to_visible_in_seconds,
553 distance_to_visible_in_pixels);
554 tile->SetPriority(tree, priority);
555 }
556 } 457 }
557 458
558 last_impl_frame_time_in_seconds_ = current_frame_time_in_seconds; 459 // Assign eventually priority to all tiles in the eventually rect that are not
460 // in the skewport.
461 for (TilingData::DifferenceIterator iter(
462 &tiling_data_, eventually_rect, skewport);
463 iter;
464 ++iter) {
465 TileMap::iterator find = tiles_.find(iter.index());
466 if (find == tiles_.end())
467 continue;
468 Tile* tile = find->second.get();
469
470 gfx::Rect tile_bounds =
471 tiling_data_.TileBounds(iter.index_x(), iter.index_y());
472
473 float distance_to_visible =
474 visible_rect_in_content_space.ManhattanInternalDistance(tile_bounds) *
475 content_to_screen_scale;
476 TilePriority priority(
477 resolution_, TilePriority::EVENTUALLY, distance_to_visible);
478 tile->SetPriority(tree, priority);
479 }
559 } 480 }
560 481
561 void PictureLayerTiling::SetLiveTilesRect( 482 void PictureLayerTiling::SetLiveTilesRect(
562 const gfx::Rect& new_live_tiles_rect) { 483 const gfx::Rect& new_live_tiles_rect) {
563 DCHECK(new_live_tiles_rect.IsEmpty() || 484 DCHECK(new_live_tiles_rect.IsEmpty() ||
564 ContentRect().Contains(new_live_tiles_rect)); 485 ContentRect().Contains(new_live_tiles_rect));
565 if (live_tiles_rect_ == new_live_tiles_rect) 486 if (live_tiles_rect_ == new_live_tiles_rect)
566 return; 487 return;
567 488
568 // Iterate to delete all tiles outside of our new live_tiles rect. 489 // Iterate to delete all tiles outside of our new live_tiles rect.
(...skipping 217 matching lines...) Expand 10 before | Expand all | Expand 10 after
786 break; 707 break;
787 } 708 }
788 709
789 gfx::Rect result(origin_x, origin_y, width, height); 710 gfx::Rect result(origin_x, origin_y, width, height);
790 if (cache) 711 if (cache)
791 cache->previous_result = result; 712 cache->previous_result = result;
792 return result; 713 return result;
793 } 714 }
794 715
795 } // namespace cc 716 } // namespace cc
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698