| OLD | NEW |
| 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/picture_layer_tiling.h" | 5 #include "cc/picture_layer_tiling.h" |
| 6 | 6 |
| 7 #include "base/debug/trace_event.h" | 7 #include "base/debug/trace_event.h" |
| 8 #include "cc/math_util.h" | 8 #include "cc/math_util.h" |
| 9 #include "ui/gfx/point_conversions.h" | 9 #include "ui/gfx/point_conversions.h" |
| 10 #include "ui/gfx/rect_conversions.h" | 10 #include "ui/gfx/rect_conversions.h" |
| 11 #include "ui/gfx/safe_integer_conversions.h" | 11 #include "ui/gfx/safe_integer_conversions.h" |
| 12 #include "ui/gfx/size_conversions.h" | 12 #include "ui/gfx/size_conversions.h" |
| 13 | 13 |
| 14 namespace cc { | 14 namespace cc { |
| 15 | 15 |
| 16 scoped_ptr<PictureLayerTiling> PictureLayerTiling::Create( | 16 scoped_ptr<PictureLayerTiling> PictureLayerTiling::Create( |
| 17 float contents_scale) { | 17 float contents_scale) { |
| 18 return make_scoped_ptr(new PictureLayerTiling(contents_scale)); | 18 return make_scoped_ptr(new PictureLayerTiling(contents_scale)); |
| 19 } | 19 } |
| 20 | 20 |
| 21 scoped_ptr<PictureLayerTiling> PictureLayerTiling::Clone() const { | 21 scoped_ptr<PictureLayerTiling> PictureLayerTiling::Clone() const { |
| 22 return make_scoped_ptr(new PictureLayerTiling(*this)); | 22 PictureLayerTiling* new_tiling = new PictureLayerTiling(*this); |
| 23 |
| 24 // The live_tiles_ list was shallow-copied, restore it explicitly. |
| 25 new_tiling->live_tiles_.clear(); |
| 26 for (TileList::const_iterator it = live_tiles_.begin(); |
| 27 it != live_tiles_.end(); ++it) { |
| 28 const TileHandle* tile_handle = *it; |
| 29 TileMap::iterator find = new_tiling->tiles_.find(tile_handle->key()); |
| 30 DCHECK(find != new_tiling->tiles_.end()); |
| 31 TileHandle* new_tile_handle = &find->second; |
| 32 new_tile_handle->AddToLiveTileList(new_tiling); |
| 33 } |
| 34 |
| 35 return make_scoped_ptr(new_tiling); |
| 23 } | 36 } |
| 24 | 37 |
| 25 PictureLayerTiling::PictureLayerTiling(float contents_scale) | 38 PictureLayerTiling::PictureLayerTiling(float contents_scale) |
| 26 : client_(NULL), | 39 : client_(NULL), |
| 27 contents_scale_(contents_scale), | 40 contents_scale_(contents_scale), |
| 28 tiling_data_(gfx::Size(), gfx::Size(), true), | 41 tiling_data_(gfx::Size(), gfx::Size(), true), |
| 29 resolution_(NON_IDEAL_RESOLUTION), | 42 resolution_(NON_IDEAL_RESOLUTION), |
| 30 last_source_frame_number_(0), | 43 last_source_frame_number_(0), |
| 31 last_impl_frame_time_(0) { | 44 last_impl_frame_time_(0) { |
| 32 } | 45 } |
| 33 | 46 |
| 34 PictureLayerTiling::~PictureLayerTiling() { | 47 PictureLayerTiling::~PictureLayerTiling() { |
| 48 tiles_.clear(); |
| 49 DCHECK(live_tiles_.empty()); |
| 35 } | 50 } |
| 36 | 51 |
| 37 void PictureLayerTiling::SetClient(PictureLayerTilingClient* client) { | 52 void PictureLayerTiling::SetClient(PictureLayerTilingClient* client) { |
| 38 client_ = client; | 53 client_ = client; |
| 39 } | 54 } |
| 40 | 55 |
| 41 gfx::Rect PictureLayerTiling::ContentRect() const { | 56 gfx::Rect PictureLayerTiling::ContentRect() const { |
| 42 return gfx::Rect(tiling_data_.total_size()); | 57 return gfx::Rect(tiling_data_.total_size()); |
| 43 } | 58 } |
| 44 | 59 |
| 45 gfx::SizeF PictureLayerTiling::ContentSizeF() const { | 60 gfx::SizeF PictureLayerTiling::ContentSizeF() const { |
| 46 return gfx::ScaleSize(layer_bounds_, contents_scale_); | 61 return gfx::ScaleSize(layer_bounds_, contents_scale_); |
| 47 } | 62 } |
| 48 | 63 |
| 49 Tile* PictureLayerTiling::TileAt(int i, int j) const { | 64 Tile* PictureLayerTiling::TileAt(int i, int j) const { |
| 50 TileMap::const_iterator iter = tiles_.find(TileMapKey(i, j)); | 65 TileMap::const_iterator iter = tiles_.find(TileMapKey(i, j)); |
| 51 if (iter == tiles_.end()) | 66 if (iter == tiles_.end()) |
| 52 return NULL; | 67 return NULL; |
| 53 return iter->second.tile(); | 68 return iter->second.tile(); |
| 54 } | 69 } |
| 55 | 70 |
| 56 void PictureLayerTiling::CreateTile(int i, int j) { | 71 void PictureLayerTiling::CreateTile(int i, int j) { |
| 57 gfx::Rect tile_rect = tiling_data_.TileBoundsWithBorder(i, j); | 72 gfx::Rect tile_rect = tiling_data_.TileBoundsWithBorder(i, j); |
| 58 tile_rect.set_size(tiling_data_.max_texture_size()); | 73 tile_rect.set_size(tiling_data_.max_texture_size()); |
| 59 TileMapKey key(i, j); | 74 TileMapKey key(i, j); |
| 60 DCHECK(tiles_.find(key) == tiles_.end()); | 75 DCHECK(tiles_.find(key) == tiles_.end()); |
| 61 scoped_refptr<Tile> tile = client_->CreateTile(this, tile_rect); | 76 scoped_refptr<Tile> tile = client_->CreateTile(this, tile_rect); |
| 62 if (tile) | 77 if (tile) |
| 63 tiles_.insert(make_pair(key, TileHandle(tile))); | 78 tiles_.insert(make_pair(key, TileHandle(key, tile))); |
| 64 } | 79 } |
| 65 | 80 |
| 66 Region PictureLayerTiling::OpaqueRegionInContentRect( | 81 Region PictureLayerTiling::OpaqueRegionInContentRect( |
| 67 const gfx::Rect& content_rect) const { | 82 const gfx::Rect& content_rect) const { |
| 68 Region opaque_region; | 83 Region opaque_region; |
| 69 // TODO(enne): implement me | 84 // TODO(enne): implement me |
| 70 return opaque_region; | 85 return opaque_region; |
| 71 } | 86 } |
| 72 | 87 |
| 73 void PictureLayerTiling::SetLayerBounds(gfx::Size layer_bounds) { | 88 void PictureLayerTiling::SetLayerBounds(gfx::Size layer_bounds) { |
| (...skipping 320 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 394 gfx::Rect inflated_rect = viewport_in_content_space; | 409 gfx::Rect inflated_rect = viewport_in_content_space; |
| 395 float adjusted_inset = TilePriority::kMaxDistanceInContentSpace / | 410 float adjusted_inset = TilePriority::kMaxDistanceInContentSpace / |
| 396 std::max(contents_scale_, 1.f); | 411 std::max(contents_scale_, 1.f); |
| 397 inflated_rect.Inset( | 412 inflated_rect.Inset( |
| 398 -adjusted_inset, | 413 -adjusted_inset, |
| 399 -adjusted_inset, | 414 -adjusted_inset, |
| 400 -adjusted_inset, | 415 -adjusted_inset, |
| 401 -adjusted_inset); | 416 -adjusted_inset); |
| 402 inflated_rect.Intersect(ContentRect()); | 417 inflated_rect.Intersect(ContentRect()); |
| 403 | 418 |
| 404 // Iterate through all of the tiles that were live last frame but will | 419 // Mark all tiles in the inflated rect as live. |
| 405 // not be live this frame, and mark them as being dead. | 420 for (TilingData::Iterator iter(&tiling_data_, inflated_rect); |
| 406 for (TilingData::DifferenceIterator iter(&tiling_data_, | 421 iter; ++iter) { |
| 407 last_prioritized_rect_, | |
| 408 inflated_rect); | |
| 409 iter; | |
| 410 ++iter) { | |
| 411 TileMap::iterator find = tiles_.find(iter.index()); | 422 TileMap::iterator find = tiles_.find(iter.index()); |
| 412 if (find == tiles_.end()) | 423 if (find == tiles_.end()) |
| 413 continue; | 424 continue; |
| 425 TileHandle* tile_handle = &find->second; |
| 426 tile_handle->set_should_be_live(true); |
| 427 tile_handle->AddToLiveTileList(this); |
| 428 } |
| 414 | 429 |
| 415 TilePriority priority; | 430 // Iterate through all of the tiles that were live last frame but will |
| 416 DCHECK(!priority.is_live); | 431 // not be live this frame, and mark them as being dead. |
| 417 TileHandle* tile_handle = &find->second; | 432 // TODO(ccameron): merge this loop with the loops below. |
| 418 Tile* tile = tile_handle->tile(); | 433 for (TileList::iterator it = live_tiles_.begin(); |
| 419 tile->set_priority(tree, priority); | 434 it != live_tiles_.end(); ) { |
| 420 tile_handle->UnregisterFromTileManager(); | 435 TileHandle* tile_handle = *it; |
| 436 TileList::iterator it_next = it; |
| 437 it_next++; |
| 438 if (!tile_handle->should_be_live() && |
| 439 !tile_handle->tile()->GetResourceId()) { |
| 440 TilePriority priority; |
| 441 DCHECK(!priority.is_live); |
| 442 tile_handle->tile()->set_priority(tree, priority); |
| 443 tile_handle->RemoveFromLiveTileList(); |
| 444 tile_handle->UnregisterFromTileManager(); |
| 445 } else { |
| 446 tile_handle->RegisterWithTileManager(); |
| 447 // Mark the tile as not live for the next time through. |
| 448 tile_handle->set_should_be_live(false); |
| 449 } |
| 450 it = it_next; |
| 421 } | 451 } |
| 452 |
| 422 last_prioritized_rect_ = inflated_rect; | 453 last_prioritized_rect_ = inflated_rect; |
| 423 | 454 |
| 424 gfx::Rect view_rect(device_viewport); | 455 gfx::Rect view_rect(device_viewport); |
| 425 float current_scale = current_layer_contents_scale / contents_scale_; | 456 float current_scale = current_layer_contents_scale / contents_scale_; |
| 426 float last_scale = last_layer_contents_scale / contents_scale_; | 457 float last_scale = last_layer_contents_scale / contents_scale_; |
| 427 | 458 |
| 428 // Fast path tile priority calculation when both transforms are translations. | 459 // Fast path tile priority calculation when both transforms are translations. |
| 429 if (last_screen_transform.IsIdentityOrTranslation() && | 460 if (last_screen_transform.IsIdentityOrTranslation() && |
| 430 current_screen_transform.IsIdentityOrTranslation()) | 461 current_screen_transform.IsIdentityOrTranslation()) |
| 431 { | 462 { |
| 432 gfx::Vector2dF current_offset( | 463 gfx::Vector2dF current_offset( |
| 433 current_screen_transform.matrix().get(0, 3), | 464 current_screen_transform.matrix().get(0, 3), |
| 434 current_screen_transform.matrix().get(1, 3)); | 465 current_screen_transform.matrix().get(1, 3)); |
| 435 gfx::Vector2dF last_offset( | 466 gfx::Vector2dF last_offset( |
| 436 last_screen_transform.matrix().get(0, 3), | 467 last_screen_transform.matrix().get(0, 3), |
| 437 last_screen_transform.matrix().get(1, 3)); | 468 last_screen_transform.matrix().get(1, 3)); |
| 438 | 469 |
| 439 for (TilingData::Iterator iter(&tiling_data_, inflated_rect); | 470 for (TileList::iterator it = live_tiles_.begin(); |
| 440 iter; ++iter) { | 471 it != live_tiles_.end(); ++it) { |
| 441 TileMap::iterator find = tiles_.find(iter.index()); | 472 TileHandle* tile_handle = *it; |
| 442 if (find == tiles_.end()) | |
| 443 continue; | |
| 444 TileHandle* tile_handle = &find->second; | |
| 445 Tile* tile = tile_handle->tile(); | 473 Tile* tile = tile_handle->tile(); |
| 446 tile_handle->RegisterWithTileManager(); | |
| 447 | 474 |
| 448 gfx::Rect tile_bounds = | 475 gfx::Rect tile_bounds = |
| 449 tiling_data_.TileBounds(iter.index_x(), iter.index_y()); | 476 tiling_data_.TileBounds(tile_handle->key().first, |
| 477 tile_handle->key().second); |
| 450 gfx::RectF current_screen_rect = gfx::ScaleRect( | 478 gfx::RectF current_screen_rect = gfx::ScaleRect( |
| 451 tile_bounds, | 479 tile_bounds, |
| 452 current_scale, | 480 current_scale, |
| 453 current_scale) + current_offset; | 481 current_scale) + current_offset; |
| 454 gfx::RectF last_screen_rect = gfx::ScaleRect( | 482 gfx::RectF last_screen_rect = gfx::ScaleRect( |
| 455 tile_bounds, | 483 tile_bounds, |
| 456 last_scale, | 484 last_scale, |
| 457 last_scale) + last_offset; | 485 last_scale) + last_offset; |
| 458 | 486 |
| 459 float distance_to_visible_in_pixels = | 487 float distance_to_visible_in_pixels = |
| 460 TilePriority::manhattanDistance(current_screen_rect, view_rect); | 488 TilePriority::manhattanDistance(current_screen_rect, view_rect); |
| 461 | 489 |
| 462 float time_to_visible_in_seconds = | 490 float time_to_visible_in_seconds = |
| 463 TilePriority::TimeForBoundsToIntersect( | 491 TilePriority::TimeForBoundsToIntersect( |
| 464 last_screen_rect, current_screen_rect, time_delta, view_rect); | 492 last_screen_rect, current_screen_rect, time_delta, view_rect); |
| 465 TilePriority priority( | 493 TilePriority priority( |
| 466 resolution_, | 494 resolution_, |
| 467 time_to_visible_in_seconds, | 495 time_to_visible_in_seconds, |
| 468 distance_to_visible_in_pixels); | 496 distance_to_visible_in_pixels); |
| 469 if (store_screen_space_quads_on_tiles) | 497 if (store_screen_space_quads_on_tiles) |
| 470 priority.set_current_screen_quad(gfx::QuadF(current_screen_rect)); | 498 priority.set_current_screen_quad(gfx::QuadF(current_screen_rect)); |
| 471 tile->set_priority(tree, priority); | 499 tile->set_priority(tree, priority); |
| 472 } | 500 } |
| 473 } else { | 501 } else { |
| 474 for (TilingData::Iterator iter(&tiling_data_, inflated_rect); | 502 for (TileList::iterator it = live_tiles_.begin(); |
| 475 iter; ++iter) { | 503 it != live_tiles_.end(); ++it) { |
| 476 TileMap::iterator find = tiles_.find(iter.index()); | 504 TileHandle* tile_handle = *it; |
| 477 if (find == tiles_.end()) | |
| 478 continue; | |
| 479 TileHandle* tile_handle = &find->second; | |
| 480 Tile* tile = tile_handle->tile(); | 505 Tile* tile = tile_handle->tile(); |
| 481 tile_handle->RegisterWithTileManager(); | |
| 482 | 506 |
| 483 gfx::Rect tile_bounds = | 507 gfx::Rect tile_bounds = |
| 484 tiling_data_.TileBounds(iter.index_x(), iter.index_y()); | 508 tiling_data_.TileBounds(tile_handle->key().first, |
| 509 tile_handle->key().second); |
| 485 gfx::RectF current_layer_content_rect = gfx::ScaleRect( | 510 gfx::RectF current_layer_content_rect = gfx::ScaleRect( |
| 486 tile_bounds, | 511 tile_bounds, |
| 487 current_scale, | 512 current_scale, |
| 488 current_scale); | 513 current_scale); |
| 489 gfx::RectF current_screen_rect = MathUtil::mapClippedRect( | 514 gfx::RectF current_screen_rect = MathUtil::mapClippedRect( |
| 490 current_screen_transform, current_layer_content_rect); | 515 current_screen_transform, current_layer_content_rect); |
| 491 gfx::RectF last_layer_content_rect = gfx::ScaleRect( | 516 gfx::RectF last_layer_content_rect = gfx::ScaleRect( |
| 492 tile_bounds, | 517 tile_bounds, |
| 493 last_scale, | 518 last_scale, |
| 494 last_scale); | 519 last_scale); |
| (...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 539 | 564 |
| 540 scoped_ptr<base::Value> PictureLayerTiling::AsValue() const { | 565 scoped_ptr<base::Value> PictureLayerTiling::AsValue() const { |
| 541 scoped_ptr<base::DictionaryValue> state(new base::DictionaryValue()); | 566 scoped_ptr<base::DictionaryValue> state(new base::DictionaryValue()); |
| 542 state->SetInteger("num_tiles", tiles_.size()); | 567 state->SetInteger("num_tiles", tiles_.size()); |
| 543 state->SetDouble("content_scale", contents_scale_); | 568 state->SetDouble("content_scale", contents_scale_); |
| 544 state->Set("content_bounds", | 569 state->Set("content_bounds", |
| 545 MathUtil::asValue(ContentRect().size()).release()); | 570 MathUtil::asValue(ContentRect().size()).release()); |
| 546 return state.PassAs<base::Value>(); | 571 return state.PassAs<base::Value>(); |
| 547 } | 572 } |
| 548 | 573 |
| 549 TileHandle::TileHandle(scoped_refptr<Tile> tile) : tile_(tile) { | 574 TileHandle::TileHandle(std::pair<int, int> key, scoped_refptr<Tile> tile) |
| 575 : key_(key), |
| 576 tile_(tile), |
| 577 should_be_live_(false), |
| 578 tiling_(NULL) { |
| 579 } |
| 580 |
| 581 TileHandle::TileHandle(const TileHandle& tile_handle) |
| 582 : key_(tile_handle.key_), |
| 583 tile_(tile_handle.tile_), |
| 584 managed_tile_state_(tile_handle.managed_tile_state_), |
| 585 should_be_live_(false), |
| 586 tiling_(NULL) { |
| 587 } |
| 588 |
| 589 TileHandle::~TileHandle() { |
| 590 RemoveFromLiveTileList(); |
| 550 } | 591 } |
| 551 | 592 |
| 552 void TileHandle::RegisterWithTileManager() { | 593 void TileHandle::RegisterWithTileManager() { |
| 553 if (managed_tile_state_.get()) | 594 if (managed_tile_state_.get()) |
| 554 return; | 595 return; |
| 555 managed_tile_state_ = tile_->tile_manager()->RegisterTile(tile_); | 596 managed_tile_state_ = tile_->tile_manager()->RegisterTile(tile_); |
| 556 } | 597 } |
| 557 | 598 |
| 558 void TileHandle::UnregisterFromTileManager() { | 599 void TileHandle::UnregisterFromTileManager() { |
| 559 managed_tile_state_ = NULL; | 600 managed_tile_state_ = NULL; |
| 560 } | 601 } |
| 561 | 602 |
| 603 void TileHandle::AddToLiveTileList(PictureLayerTiling* tiling) { |
| 604 if (tiling_) { |
| 605 DCHECK(tiling == tiling_); |
| 606 DCHECK(tiling_live_tile_list_iterator_ != tiling_->live_tiles_.end()); |
| 607 return; |
| 608 } |
| 609 tiling_ = tiling; |
| 610 tiling_live_tile_list_iterator_ = |
| 611 tiling_->live_tiles_.insert(tiling_->live_tiles_.begin(), this); |
| 612 } |
| 613 |
| 614 void TileHandle::RemoveFromLiveTileList() { |
| 615 if (!tiling_) |
| 616 return; |
| 617 tiling_->live_tiles_.erase(tiling_live_tile_list_iterator_); |
| 618 tiling_live_tile_list_iterator_ = tiling_->live_tiles_.end(); |
| 619 tiling_ = NULL; |
| 620 } |
| 621 |
| 562 } // namespace cc | 622 } // namespace cc |
| OLD | NEW |