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

Side by Side Diff: cc/layers/picture_layer_impl.cc

Issue 367833003: cc: Start using raster/eviction iterators. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: rebase Created 6 years, 2 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
« no previous file with comments | « cc/layers/picture_layer_impl.h ('k') | cc/layers/picture_layer_impl_unittest.cc » ('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/layers/picture_layer_impl.h" 5 #include "cc/layers/picture_layer_impl.h"
6 6
7 #include <algorithm> 7 #include <algorithm>
8 #include <limits> 8 #include <limits>
9 #include <set> 9 #include <set>
10 10
(...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after
68 ideal_source_scale_(0.f), 68 ideal_source_scale_(0.f),
69 ideal_contents_scale_(0.f), 69 ideal_contents_scale_(0.f),
70 raster_page_scale_(0.f), 70 raster_page_scale_(0.f),
71 raster_device_scale_(0.f), 71 raster_device_scale_(0.f),
72 raster_source_scale_(0.f), 72 raster_source_scale_(0.f),
73 raster_contents_scale_(0.f), 73 raster_contents_scale_(0.f),
74 low_res_raster_contents_scale_(0.f), 74 low_res_raster_contents_scale_(0.f),
75 raster_source_scale_is_fixed_(false), 75 raster_source_scale_is_fixed_(false),
76 was_screen_space_transform_animating_(false), 76 was_screen_space_transform_animating_(false),
77 needs_post_commit_initialization_(true), 77 needs_post_commit_initialization_(true),
78 should_update_tile_priorities_(false) { 78 should_update_tile_priorities_(false),
79 only_used_low_res_last_append_quads_(false) {
79 layer_tree_impl()->RegisterPictureLayerImpl(this); 80 layer_tree_impl()->RegisterPictureLayerImpl(this);
80 } 81 }
81 82
82 PictureLayerImpl::~PictureLayerImpl() { 83 PictureLayerImpl::~PictureLayerImpl() {
83 layer_tree_impl()->UnregisterPictureLayerImpl(this); 84 layer_tree_impl()->UnregisterPictureLayerImpl(this);
84 } 85 }
85 86
86 const char* PictureLayerImpl::LayerTypeAsString() const { 87 const char* PictureLayerImpl::LayerTypeAsString() const {
87 return "cc::PictureLayerImpl"; 88 return "cc::PictureLayerImpl";
88 } 89 }
89 90
90 scoped_ptr<LayerImpl> PictureLayerImpl::CreateLayerImpl( 91 scoped_ptr<LayerImpl> PictureLayerImpl::CreateLayerImpl(
91 LayerTreeImpl* tree_impl) { 92 LayerTreeImpl* tree_impl) {
92 return PictureLayerImpl::Create(tree_impl, id()); 93 return PictureLayerImpl::Create(tree_impl, id());
93 } 94 }
94 95
95 void PictureLayerImpl::PushPropertiesTo(LayerImpl* base_layer) { 96 void PictureLayerImpl::PushPropertiesTo(LayerImpl* base_layer) {
96 // It's possible this layer was never drawn or updated (e.g. because it was 97 // It's possible this layer was never drawn or updated (e.g. because it was
97 // a descendant of an opacity 0 layer). 98 // a descendant of an opacity 0 layer).
98 DoPostCommitInitializationIfNeeded(); 99 DoPostCommitInitializationIfNeeded();
99 PictureLayerImpl* layer_impl = static_cast<PictureLayerImpl*>(base_layer); 100 PictureLayerImpl* layer_impl = static_cast<PictureLayerImpl*>(base_layer);
100 101
101 // We have already synced the important bits from the the active layer, and
102 // we will soon swap out its tilings and use them for recycling. However,
103 // there are now tiles in this layer's tilings that were unref'd and replaced
104 // with new tiles (due to invalidation). This resets all active priorities on
105 // the to-be-recycled tiling to ensure replaced tiles don't linger and take
106 // memory (due to a stale 'active' priority).
107 if (layer_impl->tilings_)
108 layer_impl->tilings_->DidBecomeRecycled();
109
110 LayerImpl::PushPropertiesTo(base_layer); 102 LayerImpl::PushPropertiesTo(base_layer);
111 103
112 // When the pending tree pushes to the active tree, the pending twin 104 // When the pending tree pushes to the active tree, the pending twin
113 // becomes recycled. 105 // becomes recycled.
114 layer_impl->twin_layer_ = NULL; 106 layer_impl->twin_layer_ = NULL;
115 twin_layer_ = NULL; 107 twin_layer_ = NULL;
116 108
117 layer_impl->pile_ = pile_; 109 layer_impl->pile_ = pile_;
118 110
119 DCHECK(!pile_->is_solid_color() || !tilings_->num_tilings()); 111 DCHECK(!pile_->is_solid_color() || !tilings_->num_tilings());
(...skipping 124 matching lines...) Expand 10 before | Expand all | Expand 10 after
244 SkColor color; 236 SkColor color;
245 float width; 237 float width;
246 if (*iter && iter->IsReadyToDraw()) { 238 if (*iter && iter->IsReadyToDraw()) {
247 ManagedTileState::DrawInfo::Mode mode = iter->draw_info().mode(); 239 ManagedTileState::DrawInfo::Mode mode = iter->draw_info().mode();
248 if (mode == ManagedTileState::DrawInfo::SOLID_COLOR_MODE) { 240 if (mode == ManagedTileState::DrawInfo::SOLID_COLOR_MODE) {
249 color = DebugColors::SolidColorTileBorderColor(); 241 color = DebugColors::SolidColorTileBorderColor();
250 width = DebugColors::SolidColorTileBorderWidth(layer_tree_impl()); 242 width = DebugColors::SolidColorTileBorderWidth(layer_tree_impl());
251 } else if (mode == ManagedTileState::DrawInfo::PICTURE_PILE_MODE) { 243 } else if (mode == ManagedTileState::DrawInfo::PICTURE_PILE_MODE) {
252 color = DebugColors::PictureTileBorderColor(); 244 color = DebugColors::PictureTileBorderColor();
253 width = DebugColors::PictureTileBorderWidth(layer_tree_impl()); 245 width = DebugColors::PictureTileBorderWidth(layer_tree_impl());
254 } else if (iter->priority(ACTIVE_TREE).resolution == HIGH_RESOLUTION) { 246 } else if (iter.resolution() == HIGH_RESOLUTION) {
255 color = DebugColors::HighResTileBorderColor(); 247 color = DebugColors::HighResTileBorderColor();
256 width = DebugColors::HighResTileBorderWidth(layer_tree_impl()); 248 width = DebugColors::HighResTileBorderWidth(layer_tree_impl());
257 } else if (iter->priority(ACTIVE_TREE).resolution == LOW_RESOLUTION) { 249 } else if (iter.resolution() == LOW_RESOLUTION) {
258 color = DebugColors::LowResTileBorderColor(); 250 color = DebugColors::LowResTileBorderColor();
259 width = DebugColors::LowResTileBorderWidth(layer_tree_impl()); 251 width = DebugColors::LowResTileBorderWidth(layer_tree_impl());
260 } else if (iter->contents_scale() > max_contents_scale) { 252 } else if (iter->contents_scale() > max_contents_scale) {
261 color = DebugColors::ExtraHighResTileBorderColor(); 253 color = DebugColors::ExtraHighResTileBorderColor();
262 width = DebugColors::ExtraHighResTileBorderWidth(layer_tree_impl()); 254 width = DebugColors::ExtraHighResTileBorderWidth(layer_tree_impl());
263 } else { 255 } else {
264 color = DebugColors::ExtraLowResTileBorderColor(); 256 color = DebugColors::ExtraLowResTileBorderColor();
265 width = DebugColors::ExtraLowResTileBorderWidth(layer_tree_impl()); 257 width = DebugColors::ExtraLowResTileBorderWidth(layer_tree_impl());
266 } 258 }
267 } else { 259 } else {
(...skipping 18 matching lines...) Expand all
286 std::vector<PictureLayerTiling*> seen_tilings; 278 std::vector<PictureLayerTiling*> seen_tilings;
287 279
288 // Ignore missing tiles outside of viewport for tile priority. This is 280 // Ignore missing tiles outside of viewport for tile priority. This is
289 // normally the same as draw viewport but can be independently overridden by 281 // normally the same as draw viewport but can be independently overridden by
290 // embedders like Android WebView with SetExternalDrawConstraints. 282 // embedders like Android WebView with SetExternalDrawConstraints.
291 gfx::Rect scaled_viewport_for_tile_priority = gfx::ScaleToEnclosingRect( 283 gfx::Rect scaled_viewport_for_tile_priority = gfx::ScaleToEnclosingRect(
292 GetViewportForTilePriorityInContentSpace(), max_contents_scale); 284 GetViewportForTilePriorityInContentSpace(), max_contents_scale);
293 285
294 size_t missing_tile_count = 0u; 286 size_t missing_tile_count = 0u;
295 size_t on_demand_missing_tile_count = 0u; 287 size_t on_demand_missing_tile_count = 0u;
288 only_used_low_res_last_append_quads_ = true;
296 for (PictureLayerTilingSet::CoverageIterator iter(tilings_.get(), 289 for (PictureLayerTilingSet::CoverageIterator iter(tilings_.get(),
297 max_contents_scale, 290 max_contents_scale,
298 scaled_visible_content_rect, 291 scaled_visible_content_rect,
299 ideal_contents_scale_); 292 ideal_contents_scale_);
300 iter; 293 iter;
301 ++iter) { 294 ++iter) {
302 gfx::Rect geometry_rect = iter.geometry_rect(); 295 gfx::Rect geometry_rect = iter.geometry_rect();
303 gfx::Rect opaque_rect = contents_opaque() ? geometry_rect : gfx::Rect(); 296 gfx::Rect opaque_rect = contents_opaque() ? geometry_rect : gfx::Rect();
304 gfx::Rect visible_geometry_rect = 297 gfx::Rect visible_geometry_rect =
305 scaled_occlusion.GetUnoccludedContentRect(geometry_rect); 298 scaled_occlusion.GetUnoccludedContentRect(geometry_rect);
(...skipping 98 matching lines...) Expand 10 before | Expand all | Expand 10 after
404 397
405 if (geometry_rect.Intersects(scaled_viewport_for_tile_priority)) { 398 if (geometry_rect.Intersects(scaled_viewport_for_tile_priority)) {
406 append_quads_data->num_missing_tiles++; 399 append_quads_data->num_missing_tiles++;
407 ++missing_tile_count; 400 ++missing_tile_count;
408 } 401 }
409 append_quads_data->approximated_visible_content_area += 402 append_quads_data->approximated_visible_content_area +=
410 visible_geometry_rect.width() * visible_geometry_rect.height(); 403 visible_geometry_rect.width() * visible_geometry_rect.height();
411 continue; 404 continue;
412 } 405 }
413 406
414 if (iter->priority(ACTIVE_TREE).resolution != HIGH_RESOLUTION) { 407 if (iter.resolution() != HIGH_RESOLUTION) {
415 append_quads_data->approximated_visible_content_area += 408 append_quads_data->approximated_visible_content_area +=
416 visible_geometry_rect.width() * visible_geometry_rect.height(); 409 visible_geometry_rect.width() * visible_geometry_rect.height();
417 } 410 }
418 411
412 // If we have a draw quad, but it's not low resolution, then
413 // mark that we've used something other than low res to draw.
414 if (iter.resolution() != LOW_RESOLUTION)
415 only_used_low_res_last_append_quads_ = false;
416
419 if (seen_tilings.empty() || seen_tilings.back() != iter.CurrentTiling()) 417 if (seen_tilings.empty() || seen_tilings.back() != iter.CurrentTiling())
420 seen_tilings.push_back(iter.CurrentTiling()); 418 seen_tilings.push_back(iter.CurrentTiling());
421 } 419 }
422 420
423 if (missing_tile_count) { 421 if (missing_tile_count) {
424 TRACE_EVENT_INSTANT2("cc", 422 TRACE_EVENT_INSTANT2("cc",
425 "PictureLayerImpl::AppendQuads checkerboard", 423 "PictureLayerImpl::AppendQuads checkerboard",
426 TRACE_EVENT_SCOPE_THREAD, 424 TRACE_EVENT_SCOPE_THREAD,
427 "missing_tile_count", 425 "missing_tile_count",
428 missing_tile_count, 426 missing_tile_count,
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after
472 DCHECK(raster_source_scale_); 470 DCHECK(raster_source_scale_);
473 DCHECK(raster_contents_scale_); 471 DCHECK(raster_contents_scale_);
474 DCHECK(low_res_raster_contents_scale_); 472 DCHECK(low_res_raster_contents_scale_);
475 473
476 was_screen_space_transform_animating_ = 474 was_screen_space_transform_animating_ =
477 draw_properties().screen_space_transform_is_animating; 475 draw_properties().screen_space_transform_is_animating;
478 476
479 should_update_tile_priorities_ = true; 477 should_update_tile_priorities_ = true;
480 478
481 UpdateTilePriorities(occlusion_in_content_space); 479 UpdateTilePriorities(occlusion_in_content_space);
482
483 if (layer_tree_impl()->IsPendingTree())
484 MarkVisibleResourcesAsRequired();
485 } 480 }
486 481
487 void PictureLayerImpl::UpdateTilePriorities( 482 void PictureLayerImpl::UpdateTilePriorities(
488 const Occlusion& occlusion_in_content_space) { 483 const Occlusion& occlusion_in_content_space) {
489 DCHECK(!pile_->is_solid_color() || !tilings_->num_tilings()); 484 DCHECK(!pile_->is_solid_color() || !tilings_->num_tilings());
490 485
491 TRACE_EVENT0("cc", "PictureLayerImpl::UpdateTilePriorities"); 486 TRACE_EVENT0("cc", "PictureLayerImpl::UpdateTilePriorities");
492 487
493 double current_frame_time_in_seconds = 488 double current_frame_time_in_seconds =
494 (layer_tree_impl()->CurrentBeginFrameArgs().frame_time - 489 (layer_tree_impl()->CurrentBeginFrameArgs().frame_time -
495 base::TimeTicks()).InSecondsF(); 490 base::TimeTicks()).InSecondsF();
496 491
497 bool tiling_needs_update = false; 492 bool tiling_needs_update = false;
498 for (size_t i = 0; i < tilings_->num_tilings(); ++i) { 493 for (size_t i = 0; i < tilings_->num_tilings(); ++i) {
499 if (tilings_->tiling_at(i)->NeedsUpdateForFrameAtTime( 494 if (tilings_->tiling_at(i)->NeedsUpdateForFrameAtTime(
500 current_frame_time_in_seconds)) { 495 current_frame_time_in_seconds)) {
501 tiling_needs_update = true; 496 tiling_needs_update = true;
502 break; 497 break;
503 } 498 }
504 } 499 }
505 if (!tiling_needs_update) 500 if (!tiling_needs_update)
506 return; 501 return;
507 502
508 gfx::Rect viewport_rect_in_layer_space = 503 gfx::Rect viewport_rect_in_layer_space =
509 GetViewportForTilePriorityInContentSpace(); 504 GetViewportForTilePriorityInContentSpace();
510 WhichTree tree = 505 WhichTree tree =
511 layer_tree_impl()->IsActiveTree() ? ACTIVE_TREE : PENDING_TREE; 506 layer_tree_impl()->IsActiveTree() ? ACTIVE_TREE : PENDING_TREE;
507 bool can_require_tiles_for_activation =
508 !only_used_low_res_last_append_quads_ || RequiresHighResToDraw() ||
509 !layer_tree_impl()->SmoothnessTakesPriority();
512 for (size_t i = 0; i < tilings_->num_tilings(); ++i) { 510 for (size_t i = 0; i < tilings_->num_tilings(); ++i) {
511 PictureLayerTiling* tiling = tilings_->tiling_at(i);
512
513 tiling->set_can_require_tiles_for_activation(
514 can_require_tiles_for_activation);
515
513 // Pass |occlusion_in_content_space| for |occlusion_in_layer_space| since 516 // Pass |occlusion_in_content_space| for |occlusion_in_layer_space| since
514 // they are the same space in picture lbayer, as contents scale is always 1. 517 // they are the same space in picture layer, as contents scale is always 1.
515 tilings_->tiling_at(i)->UpdateTilePriorities(tree, 518 tiling->ComputeTilePriorityRects(tree,
516 viewport_rect_in_layer_space, 519 viewport_rect_in_layer_space,
517 ideal_contents_scale_, 520 ideal_contents_scale_,
518 current_frame_time_in_seconds, 521 current_frame_time_in_seconds,
519 occlusion_in_content_space); 522 occlusion_in_content_space);
520 } 523 }
521 524
522 // Tile priorities were modified. 525 // Tile priorities were modified.
526 // TODO(vmpstr): See if this can be removed in favour of calling it from LTHI
523 layer_tree_impl()->DidModifyTilePriorities(); 527 layer_tree_impl()->DidModifyTilePriorities();
524 } 528 }
525 529
526 gfx::Rect PictureLayerImpl::GetViewportForTilePriorityInContentSpace() const { 530 gfx::Rect PictureLayerImpl::GetViewportForTilePriorityInContentSpace() const {
527 // If visible_rect_for_tile_priority_ is empty or 531 // If visible_rect_for_tile_priority_ is empty or
528 // viewport_rect_for_tile_priority is set to be different from the device 532 // viewport_rect_for_tile_priority is set to be different from the device
529 // viewport, try to inverse project the viewport into layer space and use 533 // viewport, try to inverse project the viewport into layer space and use
530 // that. Otherwise just use visible_rect_for_tile_priority_ 534 // that. Otherwise just use visible_rect_for_tile_priority_
531 gfx::Rect visible_rect_in_content_space = visible_rect_for_tile_priority_; 535 gfx::Rect visible_rect_in_content_space = visible_rect_for_tile_priority_;
532 gfx::Rect viewport_rect_for_tile_priority = 536 gfx::Rect viewport_rect_for_tile_priority =
(...skipping 21 matching lines...) Expand all
554 void PictureLayerImpl::NotifyTileStateChanged(const Tile* tile) { 558 void PictureLayerImpl::NotifyTileStateChanged(const Tile* tile) {
555 if (layer_tree_impl()->IsActiveTree()) { 559 if (layer_tree_impl()->IsActiveTree()) {
556 gfx::RectF layer_damage_rect = 560 gfx::RectF layer_damage_rect =
557 gfx::ScaleRect(tile->content_rect(), 1.f / tile->contents_scale()); 561 gfx::ScaleRect(tile->content_rect(), 1.f / tile->contents_scale());
558 AddDamageRect(layer_damage_rect); 562 AddDamageRect(layer_damage_rect);
559 } 563 }
560 } 564 }
561 565
562 void PictureLayerImpl::DidBecomeActive() { 566 void PictureLayerImpl::DidBecomeActive() {
563 LayerImpl::DidBecomeActive(); 567 LayerImpl::DidBecomeActive();
564 tilings_->DidBecomeActive(); 568 // TODO(vmpstr): See if this can be removed in favour of calling it from LTHI
565 layer_tree_impl()->DidModifyTilePriorities(); 569 layer_tree_impl()->DidModifyTilePriorities();
566 } 570 }
567 571
568 void PictureLayerImpl::DidBeginTracing() { 572 void PictureLayerImpl::DidBeginTracing() {
569 pile_->DidBeginTracing(); 573 pile_->DidBeginTracing();
570 } 574 }
571 575
572 void PictureLayerImpl::ReleaseResources() { 576 void PictureLayerImpl::ReleaseResources() {
573 if (tilings_) 577 if (tilings_)
574 RemoveAllTilings(); 578 RemoveAllTilings();
(...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after
648 layer_tree_impl()->begin_impl_frame_interval().InSecondsF() * 652 layer_tree_impl()->begin_impl_frame_interval().InSecondsF() *
649 layer_tree_impl()->settings().skewport_target_time_multiplier; 653 layer_tree_impl()->settings().skewport_target_time_multiplier;
650 } 654 }
651 655
652 int PictureLayerImpl::GetSkewportExtrapolationLimitInContentPixels() const { 656 int PictureLayerImpl::GetSkewportExtrapolationLimitInContentPixels() const {
653 return layer_tree_impl() 657 return layer_tree_impl()
654 ->settings() 658 ->settings()
655 .skewport_extrapolation_limit_in_content_pixels; 659 .skewport_extrapolation_limit_in_content_pixels;
656 } 660 }
657 661
662 bool PictureLayerImpl::RequiresHighResToDraw() const {
663 return layer_tree_impl()->RequiresHighResToDraw();
664 }
665
658 gfx::Size PictureLayerImpl::CalculateTileSize( 666 gfx::Size PictureLayerImpl::CalculateTileSize(
659 const gfx::Size& content_bounds) const { 667 const gfx::Size& content_bounds) const {
660 int max_texture_size = 668 int max_texture_size =
661 layer_tree_impl()->resource_provider()->max_texture_size(); 669 layer_tree_impl()->resource_provider()->max_texture_size();
662 670
663 if (pile_->is_mask()) { 671 if (pile_->is_mask()) {
664 // Masks are not tiled, so if we can't cover the whole mask with one tile, 672 // Masks are not tiled, so if we can't cover the whole mask with one tile,
665 // don't make any tiles at all. Returning an empty size signals this. 673 // don't make any tiles at all. Returning an empty size signals this.
666 if (content_bounds.width() > max_texture_size || 674 if (content_bounds.width() > max_texture_size ||
667 content_bounds.height() > max_texture_size) 675 content_bounds.height() > max_texture_size)
(...skipping 117 matching lines...) Expand 10 before | Expand all | Expand 10 after
785 << content_rect.ToString(); 793 << content_rect.ToString();
786 794
787 const ManagedTileState::DrawInfo& draw_info = iter->draw_info(); 795 const ManagedTileState::DrawInfo& draw_info = iter->draw_info();
788 if (!draw_info.IsReadyToDraw() || 796 if (!draw_info.IsReadyToDraw() ||
789 draw_info.mode() != ManagedTileState::DrawInfo::RESOURCE_MODE) 797 draw_info.mode() != ManagedTileState::DrawInfo::RESOURCE_MODE)
790 return 0; 798 return 0;
791 799
792 return draw_info.get_resource_id(); 800 return draw_info.get_resource_id();
793 } 801 }
794 802
795 void PictureLayerImpl::MarkVisibleResourcesAsRequired() const {
796 DCHECK(layer_tree_impl()->IsPendingTree());
797 DCHECK(ideal_contents_scale_);
798 DCHECK_GT(tilings_->num_tilings(), 0u);
799
800 // The goal of this function is to find the minimum set of tiles that need to
801 // be ready to draw in order to activate without flashing content from a
802 // higher res on the active tree to a lower res on the pending tree.
803
804 // First, early out for layers with no visible content.
805 if (visible_rect_for_tile_priority_.IsEmpty())
806 return;
807
808 // Only mark tiles inside the viewport for tile priority as required for
809 // activation. This viewport is normally the same as the draw viewport but
810 // can be independently overridden by embedders like Android WebView with
811 // SetExternalDrawConstraints.
812 gfx::Rect rect = GetViewportForTilePriorityInContentSpace();
813 rect.Intersect(visible_rect_for_tile_priority_);
814
815 float min_acceptable_scale =
816 std::min(raster_contents_scale_, ideal_contents_scale_);
817
818 if (PictureLayerImpl* twin = twin_layer_) {
819 float twin_min_acceptable_scale =
820 std::min(twin->ideal_contents_scale_, twin->raster_contents_scale_);
821 // Ignore 0 scale in case CalculateContentsScale() has never been
822 // called for active twin.
823 if (twin_min_acceptable_scale != 0.0f) {
824 min_acceptable_scale =
825 std::min(min_acceptable_scale, twin_min_acceptable_scale);
826 }
827 }
828
829 PictureLayerTiling* high_res = NULL;
830 PictureLayerTiling* low_res = NULL;
831
832 // First pass: ready to draw tiles in acceptable but non-ideal tilings are
833 // marked as required for activation so that their textures are not thrown
834 // away; any non-ready tiles are not marked as required.
835 Region missing_region = rect;
836 for (size_t i = 0; i < tilings_->num_tilings(); ++i) {
837 PictureLayerTiling* tiling = tilings_->tiling_at(i);
838 DCHECK(tiling->has_ever_been_updated());
839
840 if (tiling->resolution() == LOW_RESOLUTION) {
841 DCHECK(!low_res) << "There can only be one low res tiling";
842 low_res = tiling;
843 }
844 if (tiling->contents_scale() < min_acceptable_scale)
845 continue;
846 if (tiling->resolution() == HIGH_RESOLUTION) {
847 DCHECK(!high_res) << "There can only be one high res tiling";
848 high_res = tiling;
849 continue;
850 }
851 for (PictureLayerTiling::CoverageIterator iter(tiling, 1.f, rect); iter;
852 ++iter) {
853 if (!*iter || !iter->IsReadyToDraw())
854 continue;
855
856 missing_region.Subtract(iter.geometry_rect());
857 iter->MarkRequiredForActivation();
858 }
859 }
860 DCHECK(high_res) << "There must be one high res tiling";
861
862 // If these pointers are null (because no twin, no matching tiling, or the
863 // simpification just below), then high res tiles will be required to fill any
864 // holes left by the first pass above. If the pointers are valid, then this
865 // layer is allowed to skip any tiles that are not ready on its twin.
866 const PictureLayerTiling* twin_high_res = NULL;
867 const PictureLayerTiling* twin_low_res = NULL;
868
869 if (twin_layer_) {
870 // As a simplification, only allow activating to skip twin tiles that the
871 // active layer is also missing when both this layer and its twin have
872 // "simple" sets of tilings: only 2 tilings (high and low) or only 1 high
873 // res tiling. This avoids having to iterate/track coverage of non-ideal
874 // tilings during the last draw call on the active layer.
875 if (tilings_->num_tilings() <= 2 &&
876 twin_layer_->tilings_->num_tilings() <= tilings_->num_tilings()) {
877 twin_low_res = low_res ? GetTwinTiling(low_res) : NULL;
878 twin_high_res = high_res ? GetTwinTiling(high_res) : NULL;
879 }
880
881 // If this layer and its twin have different transforms, then don't compare
882 // them and only allow activating to high res tiles, since tiles on each
883 // layer will be in different places on screen.
884 if (layer_tree_impl()->RequiresHighResToDraw() ||
885 bounds() != twin_layer_->bounds() ||
886 draw_properties().screen_space_transform !=
887 twin_layer_->draw_properties().screen_space_transform) {
888 twin_high_res = NULL;
889 twin_low_res = NULL;
890 }
891 }
892
893 // As a second pass, mark as required any visible high res tiles not filled in
894 // by acceptable non-ideal tiles from the first pass.
895 if (MarkVisibleTilesAsRequired(
896 high_res, twin_high_res, rect, missing_region)) {
897 // As an optional third pass, if a high res tile was skipped because its
898 // twin was also missing, then fall back to mark low res tiles as required
899 // in case the active twin is substituting those for missing high res
900 // content. Only suitable, when low res is enabled.
901 if (low_res) {
902 MarkVisibleTilesAsRequired(low_res, twin_low_res, rect, missing_region);
903 }
904 }
905 }
906
907 bool PictureLayerImpl::MarkVisibleTilesAsRequired(
908 PictureLayerTiling* tiling,
909 const PictureLayerTiling* optional_twin_tiling,
910 const gfx::Rect& rect,
911 const Region& missing_region) const {
912 bool twin_had_missing_tile = false;
913 for (PictureLayerTiling::CoverageIterator iter(tiling, 1.f, rect); iter;
914 ++iter) {
915 Tile* tile = *iter;
916 // A null tile (i.e. missing recording) can just be skipped.
917 if (!tile)
918 continue;
919
920 // If the tile is occluded, don't mark it as required for activation.
921 if (tile->is_occluded(PENDING_TREE))
922 continue;
923
924 // If the missing region doesn't cover it, this tile is fully
925 // covered by acceptable tiles at other scales.
926 if (!missing_region.Intersects(iter.geometry_rect()))
927 continue;
928
929 // If the twin tile doesn't exist (i.e. missing recording or so far away
930 // that it is outside the visible tile rect) or this tile is shared between
931 // with the twin, then this tile isn't required to prevent flashing.
932 if (optional_twin_tiling) {
933 Tile* twin_tile = optional_twin_tiling->TileAt(iter.i(), iter.j());
934 if (!twin_tile || twin_tile == tile) {
935 // However if the shared tile is being used on the active tree, then
936 // there's no missing content in this place, and low res is not needed.
937 if (!twin_tile || !twin_tile->IsReadyToDraw())
938 twin_had_missing_tile = true;
939 continue;
940 }
941 }
942
943 tile->MarkRequiredForActivation();
944 }
945 return twin_had_missing_tile;
946 }
947
948 void PictureLayerImpl::DoPostCommitInitialization() { 803 void PictureLayerImpl::DoPostCommitInitialization() {
949 DCHECK(needs_post_commit_initialization_); 804 DCHECK(needs_post_commit_initialization_);
950 DCHECK(layer_tree_impl()->IsPendingTree()); 805 DCHECK(layer_tree_impl()->IsPendingTree());
951 806
952 if (!tilings_) 807 if (!tilings_)
953 tilings_.reset(new PictureLayerTilingSet(this, bounds())); 808 tilings_.reset(new PictureLayerTilingSet(this, bounds()));
954 809
955 DCHECK(!twin_layer_); 810 DCHECK(!twin_layer_);
956 twin_layer_ = static_cast<PictureLayerImpl*>( 811 twin_layer_ = static_cast<PictureLayerImpl*>(
957 layer_tree_impl()->FindActiveTreeLayerById(id())); 812 layer_tree_impl()->FindActiveTreeLayerById(id()));
(...skipping 377 matching lines...) Expand 10 before | Expand all | Expand 10 after
1335 if (layer_tree_impl()->IsRecycleTree()) 1190 if (layer_tree_impl()->IsRecycleTree())
1336 return; 1191 return;
1337 1192
1338 if (!CanHaveTilings()) { 1193 if (!CanHaveTilings()) {
1339 DCHECK_EQ(0u, tilings_->num_tilings()); 1194 DCHECK_EQ(0u, tilings_->num_tilings());
1340 return; 1195 return;
1341 } 1196 }
1342 if (tilings_->num_tilings() == 0) 1197 if (tilings_->num_tilings() == 0)
1343 return; 1198 return;
1344 1199
1345 // MarkVisibleResourcesAsRequired depends on having exactly 1 high res 1200 // We should only have one high res tiling.
1346 // tiling to mark its tiles as being required for activation.
1347 DCHECK_EQ(1, tilings_->NumHighResTilings()); 1201 DCHECK_EQ(1, tilings_->NumHighResTilings());
1348 #endif 1202 #endif
1349 } 1203 }
1350 1204
1351 bool PictureLayerImpl::ShouldAdjustRasterScaleDuringScaleAnimations() const { 1205 bool PictureLayerImpl::ShouldAdjustRasterScaleDuringScaleAnimations() const {
1352 if (!layer_tree_impl()->use_gpu_rasterization()) 1206 if (!layer_tree_impl()->use_gpu_rasterization())
1353 return false; 1207 return false;
1354 1208
1355 // Re-rastering text at different scales using GPU rasterization causes 1209 // Re-rastering text at different scales using GPU rasterization causes
1356 // texture uploads for glyphs at each scale (see crbug.com/366225). To 1210 // texture uploads for glyphs at each scale (see crbug.com/366225). To
(...skipping 140 matching lines...) Expand 10 before | Expand all | Expand 10 after
1497 for (size_t i = 0; i < tilings_->num_tilings(); ++i) { 1351 for (size_t i = 0; i < tilings_->num_tilings(); ++i) {
1498 PictureLayerTiling* tiling = tilings_->tiling_at(i); 1352 PictureLayerTiling* tiling = tilings_->tiling_at(i);
1499 if (tiling->resolution() != HIGH_RESOLUTION && 1353 if (tiling->resolution() != HIGH_RESOLUTION &&
1500 tiling->resolution() != LOW_RESOLUTION) 1354 tiling->resolution() != LOW_RESOLUTION)
1501 continue; 1355 continue;
1502 1356
1503 for (PictureLayerTiling::CoverageIterator iter(tiling, 1.f, rect); iter; 1357 for (PictureLayerTiling::CoverageIterator iter(tiling, 1.f, rect); iter;
1504 ++iter) { 1358 ++iter) {
1505 const Tile* tile = *iter; 1359 const Tile* tile = *iter;
1506 // A null tile (i.e. missing recording) can just be skipped. 1360 // A null tile (i.e. missing recording) can just be skipped.
1361 // TODO(vmpstr): Verify this is true if we create tiles in raster
1362 // iterators.
1507 if (!tile) 1363 if (!tile)
1508 continue; 1364 continue;
1509 1365
1510 if (tile->required_for_activation() && !tile->IsReadyToDraw()) 1366 // We can't check tile->required_for_activation, because that value might
1367 // be out of date. It is updated in the raster/eviction iterators.
1368 // TODO(vmpstr): Remove the comment once you can't access this information
1369 // from the tile.
1370 if (tiling->IsTileRequiredForActivation(tile) && !tile->IsReadyToDraw())
1511 return false; 1371 return false;
1512 } 1372 }
1513 } 1373 }
1514 1374
1515 return true; 1375 return true;
1516 } 1376 }
1517 1377
1518 PictureLayerImpl::LayerRasterTileIterator::LayerRasterTileIterator() 1378 PictureLayerImpl::LayerRasterTileIterator::LayerRasterTileIterator()
1519 : layer_(NULL), current_stage_(arraysize(stages_)) { 1379 : layer_(NULL), current_stage_(arraysize(stages_)) {
1520 } 1380 }
(...skipping 10 matching lines...) Expand all
1531 return; 1391 return;
1532 } 1392 }
1533 1393
1534 // Tiles without valid priority are treated as having lowest priority and 1394 // Tiles without valid priority are treated as having lowest priority and
1535 // never considered for raster. 1395 // never considered for raster.
1536 if (!layer_->HasValidTilePriorities()) { 1396 if (!layer_->HasValidTilePriorities()) {
1537 current_stage_ = arraysize(stages_); 1397 current_stage_ = arraysize(stages_);
1538 return; 1398 return;
1539 } 1399 }
1540 1400
1541 WhichTree tree = layer_->GetTree();
1542
1543 // Find high and low res tilings and initialize the iterators. 1401 // Find high and low res tilings and initialize the iterators.
1544 for (size_t i = 0; i < layer_->tilings_->num_tilings(); ++i) { 1402 for (size_t i = 0; i < layer_->tilings_->num_tilings(); ++i) {
1545 PictureLayerTiling* tiling = layer_->tilings_->tiling_at(i); 1403 PictureLayerTiling* tiling = layer_->tilings_->tiling_at(i);
1546 if (tiling->resolution() == HIGH_RESOLUTION) { 1404 if (tiling->resolution() == HIGH_RESOLUTION) {
1547 iterators_[HIGH_RES] = 1405 iterators_[HIGH_RES] =
1548 PictureLayerTiling::TilingRasterTileIterator(tiling, tree); 1406 PictureLayerTiling::TilingRasterTileIterator(tiling);
1549 } 1407 }
1550 1408
1551 if (tiling->resolution() == LOW_RESOLUTION) { 1409 if (tiling->resolution() == LOW_RESOLUTION) {
1552 iterators_[LOW_RES] = 1410 iterators_[LOW_RES] =
1553 PictureLayerTiling::TilingRasterTileIterator(tiling, tree); 1411 PictureLayerTiling::TilingRasterTileIterator(tiling);
1554 } 1412 }
1555 } 1413 }
1556 1414
1557 if (prioritize_low_res) { 1415 if (prioritize_low_res) {
1558 stages_[0].iterator_type = LOW_RES; 1416 stages_[0].iterator_type = LOW_RES;
1559 stages_[0].tile_type = TilePriority::NOW; 1417 stages_[0].tile_type = TilePriority::NOW;
1560 1418
1561 stages_[1].iterator_type = HIGH_RES; 1419 stages_[1].iterator_type = HIGH_RES;
1562 stages_[1].tile_type = TilePriority::NOW; 1420 stages_[1].tile_type = TilePriority::NOW;
1563 } else { 1421 } else {
(...skipping 219 matching lines...) Expand 10 before | Expand all | Expand 10 after
1783 PictureLayerTilingSet::TilingRange tiling_range = CurrentTilingRange(); 1641 PictureLayerTilingSet::TilingRange tiling_range = CurrentTilingRange();
1784 size_t current_tiling_range_offset = current_tiling_ - tiling_range.start; 1642 size_t current_tiling_range_offset = current_tiling_ - tiling_range.start;
1785 return tiling_range.end - 1 - current_tiling_range_offset; 1643 return tiling_range.end - 1 - current_tiling_range_offset;
1786 } 1644 }
1787 } 1645 }
1788 NOTREACHED(); 1646 NOTREACHED();
1789 return 0; 1647 return 0;
1790 } 1648 }
1791 1649
1792 } // namespace cc 1650 } // namespace cc
OLDNEW
« no previous file with comments | « cc/layers/picture_layer_impl.h ('k') | cc/layers/picture_layer_impl_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698