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

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: update 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(
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 // Note that if the viewport is growing very rapidly, then
enne (OOO) 2014/02/11 23:51:49 This seems unfortunate. What about cases where th
vmpstr 2014/02/12 00:27:52 Yeah, the problem is that if I limit width by 2 *
370 // the skewport limit will be more limiting than it appears.
371 // That is, if x moves by limit pixels, then width will be
372 // at most limit pixels as well. Thus, if x moves to the left,
373 // the skewport will not be extended to the right.
374 int skewport_limit = client_->GetSkewportExtrapolationLimitInContentPixels();
375 int x_adjustment = std::min<int>(
376 std::abs(extrapolation_multiplier * (new_x - old_x)), skewport_limit);
377 if (new_x < old_x)
378 x_adjustment *= -1;
379
380 int y_adjustment = std::min<int>(
381 std::abs(extrapolation_multiplier * (new_y - old_y)), skewport_limit);
382 if (new_y < old_y)
383 y_adjustment *= -1;
384
385 int width_adjustment = std::min<int>(
386 extrapolation_multiplier * (new_width - old_width), skewport_limit);
387 int height_adjustment = std::min<int>(
388 extrapolation_multiplier * (new_height - old_height), skewport_limit);
389
390 skewport.set_width(skewport.width() + width_adjustment);
391 skewport.set_height(skewport.height() + height_adjustment);
392 skewport.set_x(skewport.x() + x_adjustment);
393 skewport.set_y(skewport.y() + y_adjustment);
394
395 skewport.Union(visible_rect_in_content_space);
396 return skewport;
397 }
398
342 void PictureLayerTiling::UpdateTilePriorities( 399 void PictureLayerTiling::UpdateTilePriorities(
343 WhichTree tree, 400 WhichTree tree,
344 const gfx::Size& device_viewport,
345 const gfx::Rect& viewport_in_layer_space,
346 const gfx::Rect& visible_layer_rect, 401 const gfx::Rect& visible_layer_rect,
347 const gfx::Size& last_layer_bounds, 402 float layer_contents_scale,
348 const gfx::Size& current_layer_bounds, 403 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)) { 404 if (!NeedsUpdateForFrameAtTime(current_frame_time_in_seconds)) {
356 // This should never be zero for the purposes of has_ever_been_updated(). 405 // This should never be zero for the purposes of has_ever_been_updated().
357 DCHECK_NE(current_frame_time_in_seconds, 0.0); 406 DCHECK_NE(current_frame_time_in_seconds, 0.0);
358 return; 407 return;
359 } 408 }
409
410 gfx::Rect visible_rect_in_content_space =
411 gfx::ScaleToEnclosingRect(visible_layer_rect, contents_scale_);
412
360 if (ContentRect().IsEmpty()) { 413 if (ContentRect().IsEmpty()) {
361 last_impl_frame_time_in_seconds_ = current_frame_time_in_seconds; 414 last_impl_frame_time_in_seconds_ = current_frame_time_in_seconds;
415 last_visible_rect_in_content_space_ = visible_rect_in_content_space;
362 return; 416 return;
363 } 417 }
364 418
365 gfx::Rect viewport_in_content_space = 419 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 420
370 gfx::Size tile_size = tiling_data_.max_texture_size(); 421 gfx::Size tile_size = tiling_data_.max_texture_size();
371 int64 interest_rect_area = 422 int64 eventually_rect_area =
372 max_tiles_for_interest_area * tile_size.width() * tile_size.height(); 423 max_tiles_for_interest_area * tile_size.width() * tile_size.height();
373 424
374 gfx::Rect starting_rect = visible_content_rect.IsEmpty() 425 gfx::Rect skewport = ComputeSkewport(current_frame_time_in_seconds,
375 ? viewport_in_content_space 426 visible_rect_in_content_space);
376 : visible_content_rect; 427 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 428
385 SetLiveTilesRect(interest_rect); 429 gfx::Rect eventually_rect =
430 ExpandRectEquallyToAreaBoundedBy(visible_rect_in_content_space,
431 eventually_rect_area,
432 ContentRect(),
433 &expansion_cache_);
386 434
387 double time_delta = 0; 435 DCHECK(eventually_rect.IsEmpty() || ContentRect().Contains(eventually_rect));
388 if (last_impl_frame_time_in_seconds_ != 0.0 && 436
389 last_layer_bounds == current_layer_bounds) { 437 SetLiveTilesRect(eventually_rect);
390 time_delta = 438
391 current_frame_time_in_seconds - last_impl_frame_time_in_seconds_; 439 last_impl_frame_time_in_seconds_ = current_frame_time_in_seconds;
440 last_visible_rect_in_content_space_ = visible_rect_in_content_space;
441
442 // Assign now priority to all visible tiles.
443 TilePriority now_priority(resolution_, TilePriority::NOW, 0);
444 for (TilingData::Iterator iter(&tiling_data_, visible_rect_in_content_space);
445 iter;
446 ++iter) {
447 TileMap::iterator find = tiles_.find(iter.index());
448 if (find == tiles_.end())
449 continue;
450 Tile* tile = find->second.get();
451
452 tile->SetPriority(tree, now_priority);
392 } 453 }
393 454
394 gfx::RectF view_rect(device_viewport); 455 // Assign soon priority to all tiles in the skewport that are not visible.
395 float current_scale = current_layer_contents_scale / contents_scale_; 456 float content_to_screen_scale =
396 float last_scale = last_layer_contents_scale / contents_scale_; 457 1.0f / (contents_scale_ * layer_contents_scale);
458 for (TilingData::DifferenceIterator iter(
459 &tiling_data_, skewport, visible_rect_in_content_space);
460 iter;
461 ++iter) {
462 TileMap::iterator find = tiles_.find(iter.index());
463 if (find == tiles_.end())
464 continue;
465 Tile* tile = find->second.get();
397 466
398 // Fast path tile priority calculation when both transforms are translations. 467 gfx::Rect tile_bounds =
399 if (last_screen_transform.IsApproximatelyIdentityOrTranslation( 468 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 469
410 for (TilingData::Iterator iter(&tiling_data_, interest_rect); 470 float distance_to_visible =
411 iter; ++iter) { 471 visible_rect_in_content_space.ManhattanInternalDistance(tile_bounds) *
412 TileMap::iterator find = tiles_.find(iter.index()); 472 content_to_screen_scale;
413 if (find == tiles_.end())
414 continue;
415 Tile* tile = find->second.get();
416 473
417 gfx::Rect tile_bounds = 474 TilePriority priority(resolution_, TilePriority::SOON, distance_to_visible);
418 tiling_data_.TileBounds(iter.index_x(), iter.index_y()); 475 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 } 476 }
557 477
558 last_impl_frame_time_in_seconds_ = current_frame_time_in_seconds; 478 // Assign eventually priority to all tiles in the eventually rect that are not
479 // in the skewport.
480 for (TilingData::DifferenceIterator iter(
481 &tiling_data_, eventually_rect, skewport);
482 iter;
483 ++iter) {
484 TileMap::iterator find = tiles_.find(iter.index());
485 if (find == tiles_.end())
486 continue;
487 Tile* tile = find->second.get();
488
489 gfx::Rect tile_bounds =
490 tiling_data_.TileBounds(iter.index_x(), iter.index_y());
491
492 float distance_to_visible =
493 visible_rect_in_content_space.ManhattanInternalDistance(tile_bounds) *
494 content_to_screen_scale;
495 TilePriority priority(
496 resolution_, TilePriority::EVENTUALLY, distance_to_visible);
497 tile->SetPriority(tree, priority);
498 }
559 } 499 }
560 500
561 void PictureLayerTiling::SetLiveTilesRect( 501 void PictureLayerTiling::SetLiveTilesRect(
562 const gfx::Rect& new_live_tiles_rect) { 502 const gfx::Rect& new_live_tiles_rect) {
563 DCHECK(new_live_tiles_rect.IsEmpty() || 503 DCHECK(new_live_tiles_rect.IsEmpty() ||
564 ContentRect().Contains(new_live_tiles_rect)); 504 ContentRect().Contains(new_live_tiles_rect));
565 if (live_tiles_rect_ == new_live_tiles_rect) 505 if (live_tiles_rect_ == new_live_tiles_rect)
566 return; 506 return;
567 507
568 // Iterate to delete all tiles outside of our new live_tiles rect. 508 // 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; 726 break;
787 } 727 }
788 728
789 gfx::Rect result(origin_x, origin_y, width, height); 729 gfx::Rect result(origin_x, origin_y, width, height);
790 if (cache) 730 if (cache)
791 cache->previous_result = result; 731 cache->previous_result = result;
792 return result; 732 return result;
793 } 733 }
794 734
795 } // namespace cc 735 } // namespace cc
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698