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

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: format + clip inverse projected rect 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
11 #include "base/debug/trace_event.h" 11 #include "base/debug/trace_event.h"
12 #include "cc/base/math_util.h" 12 #include "cc/base/math_util.h"
13 #include "ui/gfx/point_conversions.h" 13 #include "ui/gfx/point_conversions.h"
14 #include "ui/gfx/rect_conversions.h" 14 #include "ui/gfx/rect_conversions.h"
15 #include "ui/gfx/safe_integer_conversions.h" 15 #include "ui/gfx/safe_integer_conversions.h"
16 #include "ui/gfx/size_conversions.h" 16 #include "ui/gfx/size_conversions.h"
17 17
18 namespace cc { 18 namespace cc {
19 19
20 namespace {
21 int kSkewportExtrapolatedLimitInContentPixels = 2000;
enne (OOO) 2014/02/11 00:43:56 Should this be a LayerTreeSetting?
vmpstr 2014/02/11 23:45:25 Done.
22 }
23
20 scoped_ptr<PictureLayerTiling> PictureLayerTiling::Create( 24 scoped_ptr<PictureLayerTiling> PictureLayerTiling::Create(
21 float contents_scale, 25 float contents_scale,
22 const gfx::Size& layer_bounds, 26 const gfx::Size& layer_bounds,
23 PictureLayerTilingClient* client) { 27 PictureLayerTilingClient* client) {
24 return make_scoped_ptr(new PictureLayerTiling(contents_scale, 28 return make_scoped_ptr(new PictureLayerTiling(contents_scale,
25 layer_bounds, 29 layer_bounds,
26 client)); 30 client));
27 } 31 }
28 32
29 PictureLayerTiling::PictureLayerTiling(float contents_scale, 33 PictureLayerTiling::PictureLayerTiling(float contents_scale,
(...skipping 302 matching lines...) Expand 10 before | Expand all | Expand 10 after
332 336
333 gfx::Size PictureLayerTiling::CoverageIterator::texture_size() const { 337 gfx::Size PictureLayerTiling::CoverageIterator::texture_size() const {
334 return tiling_->tiling_data_.max_texture_size(); 338 return tiling_->tiling_data_.max_texture_size();
335 } 339 }
336 340
337 void PictureLayerTiling::Reset() { 341 void PictureLayerTiling::Reset() {
338 live_tiles_rect_ = gfx::Rect(); 342 live_tiles_rect_ = gfx::Rect();
339 tiles_.clear(); 343 tiles_.clear();
340 } 344 }
341 345
346 gfx::Rect PictureLayerTiling::ComputeSkewport(
347 double current_frame_time_in_seconds,
348 const gfx::Rect& visible_rect_in_content_space) const {
349 gfx::Rect skewport = visible_rect_in_content_space;
350 if (last_impl_frame_time_in_seconds_ == 0.0)
351 return skewport;
352
353 double time_delta =
354 current_frame_time_in_seconds - last_impl_frame_time_in_seconds_;
355 if (time_delta == 0.0)
356 return skewport;
357
358 float skewport_target_time_in_seconds =
359 client_->GetSkewportTargetTimeInSeconds();
360 double extrapolation_multiplier =
361 skewport_target_time_in_seconds / time_delta;
362
363 int old_width = last_visible_rect_in_content_space_.width();
364 int old_height = last_visible_rect_in_content_space_.height();
365 int old_x = last_visible_rect_in_content_space_.x();
366 int old_y = last_visible_rect_in_content_space_.y();
367
368 int new_width = visible_rect_in_content_space.width();
369 int new_height = visible_rect_in_content_space.height();
370 int new_x = visible_rect_in_content_space.x();
371 int new_y = visible_rect_in_content_space.y();
372
373 int x_adjustment = std::min<int>(extrapolation_multiplier * (new_x - old_x),
374 kSkewportExtrapolatedLimitInContentPixels);
375 int y_adjustment = std::min<int>(extrapolation_multiplier * (new_y - old_y),
376 kSkewportExtrapolatedLimitInContentPixels);
377 int width_adjustment =
378 std::min<int>(extrapolation_multiplier * (new_width - old_width),
379 kSkewportExtrapolatedLimitInContentPixels);
380 int height_adjustment =
381 std::min<int>(extrapolation_multiplier * (new_height - old_height),
382 kSkewportExtrapolatedLimitInContentPixels);
383
384 skewport.set_width(skewport.width() + width_adjustment);
385 skewport.set_height(skewport.height() + height_adjustment);
386 skewport.set_x(skewport.x() + x_adjustment);
387 skewport.set_y(skewport.y() + y_adjustment);
388
389 skewport.Union(visible_rect_in_content_space);
390 return skewport;
391 }
392
342 void PictureLayerTiling::UpdateTilePriorities( 393 void PictureLayerTiling::UpdateTilePriorities(
343 WhichTree tree, 394 WhichTree tree,
344 const gfx::Size& device_viewport,
345 const gfx::Rect& viewport_in_layer_space,
346 const gfx::Rect& visible_layer_rect, 395 const gfx::Rect& visible_layer_rect,
347 const gfx::Size& last_layer_bounds, 396 float layer_contents_scale,
348 const gfx::Size& current_layer_bounds, 397 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)) { 398 if (!NeedsUpdateForFrameAtTime(current_frame_time_in_seconds)) {
356 // This should never be zero for the purposes of has_ever_been_updated(). 399 // This should never be zero for the purposes of has_ever_been_updated().
357 DCHECK_NE(current_frame_time_in_seconds, 0.0); 400 DCHECK_NE(current_frame_time_in_seconds, 0.0);
358 return; 401 return;
359 } 402 }
403
404 gfx::Rect visible_rect_in_content_space =
405 gfx::ScaleToEnclosingRect(visible_layer_rect, contents_scale_);
406
360 if (ContentRect().IsEmpty()) { 407 if (ContentRect().IsEmpty()) {
361 last_impl_frame_time_in_seconds_ = current_frame_time_in_seconds; 408 last_impl_frame_time_in_seconds_ = current_frame_time_in_seconds;
409 last_visible_rect_in_content_space_ = visible_rect_in_content_space;
362 return; 410 return;
363 } 411 }
364 412
365 gfx::Rect viewport_in_content_space = 413 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 414
370 gfx::Size tile_size = tiling_data_.max_texture_size(); 415 gfx::Size tile_size = tiling_data_.max_texture_size();
371 int64 interest_rect_area = 416 int64 eventually_rect_area =
372 max_tiles_for_interest_area * tile_size.width() * tile_size.height(); 417 max_tiles_for_interest_area * tile_size.width() * tile_size.height();
373 418
374 gfx::Rect starting_rect = visible_content_rect.IsEmpty() 419 gfx::Rect skewport = ComputeSkewport(current_frame_time_in_seconds,
375 ? viewport_in_content_space 420 visible_rect_in_content_space);
376 : visible_content_rect; 421 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 422
385 SetLiveTilesRect(interest_rect); 423 gfx::Rect eventually_rect =
424 ExpandRectEquallyToAreaBoundedBy(visible_rect_in_content_space,
425 eventually_rect_area,
426 ContentRect(),
427 &expansion_cache_);
428 DCHECK(eventually_rect.IsEmpty() || ContentRect().Contains(eventually_rect));
386 429
387 double time_delta = 0; 430 SetLiveTilesRect(eventually_rect);
388 if (last_impl_frame_time_in_seconds_ != 0.0 && 431
389 last_layer_bounds == current_layer_bounds) { 432 last_impl_frame_time_in_seconds_ = current_frame_time_in_seconds;
390 time_delta = 433 last_visible_rect_in_content_space_ = visible_rect_in_content_space;
391 current_frame_time_in_seconds - last_impl_frame_time_in_seconds_; 434
435 // Assign now priority to all visible tiles.
436 TilePriority now_priority(resolution_, TilePriority::NOW, 0);
437 for (TilingData::Iterator iter(&tiling_data_, visible_rect_in_content_space);
438 iter;
439 ++iter) {
440 TileMap::iterator find = tiles_.find(iter.index());
441 if (find == tiles_.end())
442 continue;
443 Tile* tile = find->second.get();
444
445 tile->SetPriority(tree, now_priority);
392 } 446 }
393 447
394 gfx::RectF view_rect(device_viewport); 448 // Assign soon priority to all tiles in the skewport that are not visible.
395 float current_scale = current_layer_contents_scale / contents_scale_; 449 float content_to_screen_scale =
396 float last_scale = last_layer_contents_scale / contents_scale_; 450 1.0f / (contents_scale_ * layer_contents_scale);
451 for (TilingData::DifferenceIterator iter(
452 &tiling_data_, skewport, visible_rect_in_content_space);
453 iter;
454 ++iter) {
455 TileMap::iterator find = tiles_.find(iter.index());
456 if (find == tiles_.end())
457 continue;
458 Tile* tile = find->second.get();
397 459
398 // Fast path tile priority calculation when both transforms are translations. 460 gfx::Rect tile_bounds =
399 if (last_screen_transform.IsApproximatelyIdentityOrTranslation( 461 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 462
410 for (TilingData::Iterator iter(&tiling_data_, interest_rect); 463 float distance_to_visible =
411 iter; ++iter) { 464 visible_rect_in_content_space.ManhattanInternalDistance(tile_bounds) *
412 TileMap::iterator find = tiles_.find(iter.index()); 465 content_to_screen_scale;
413 if (find == tiles_.end())
414 continue;
415 Tile* tile = find->second.get();
416 466
417 gfx::Rect tile_bounds = 467 TilePriority priority(resolution_, TilePriority::SOON, distance_to_visible);
418 tiling_data_.TileBounds(iter.index_x(), iter.index_y()); 468 tile->SetPriority(tree, priority);
419 gfx::RectF current_screen_rect = gfx::ScaleRect(
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 } 469 }
557 470
558 last_impl_frame_time_in_seconds_ = current_frame_time_in_seconds; 471 // Assign eventually priority to all tiles in the eventually rect that are not
472 // in the skewport.
473 for (TilingData::DifferenceIterator iter(
474 &tiling_data_, eventually_rect, skewport);
475 iter;
476 ++iter) {
477 TileMap::iterator find = tiles_.find(iter.index());
478 if (find == tiles_.end())
479 continue;
480 Tile* tile = find->second.get();
481
482 gfx::Rect tile_bounds =
483 tiling_data_.TileBounds(iter.index_x(), iter.index_y());
484
485 float distance_to_visible =
486 visible_rect_in_content_space.ManhattanInternalDistance(tile_bounds) *
487 content_to_screen_scale;
488 TilePriority priority(
489 resolution_, TilePriority::EVENTUALLY, distance_to_visible);
490 tile->SetPriority(tree, priority);
491 }
559 } 492 }
560 493
561 void PictureLayerTiling::SetLiveTilesRect( 494 void PictureLayerTiling::SetLiveTilesRect(
562 const gfx::Rect& new_live_tiles_rect) { 495 const gfx::Rect& new_live_tiles_rect) {
563 DCHECK(new_live_tiles_rect.IsEmpty() || 496 DCHECK(new_live_tiles_rect.IsEmpty() ||
564 ContentRect().Contains(new_live_tiles_rect)); 497 ContentRect().Contains(new_live_tiles_rect));
565 if (live_tiles_rect_ == new_live_tiles_rect) 498 if (live_tiles_rect_ == new_live_tiles_rect)
566 return; 499 return;
567 500
568 // Iterate to delete all tiles outside of our new live_tiles rect. 501 // 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; 719 break;
787 } 720 }
788 721
789 gfx::Rect result(origin_x, origin_y, width, height); 722 gfx::Rect result(origin_x, origin_y, width, height);
790 if (cache) 723 if (cache)
791 cache->previous_result = result; 724 cache->previous_result = result;
792 return result; 725 return result;
793 } 726 }
794 727
795 } // namespace cc 728 } // namespace cc
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698