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

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

Issue 1939963002: cc: Move prepaint region calculations to the tiling set. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 4 years, 7 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
« no previous file with comments | « cc/tiles/picture_layer_tiling.h ('k') | cc/tiles/picture_layer_tiling_perftest.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/tiles/picture_layer_tiling.h" 5 #include "cc/tiles/picture_layer_tiling.h"
6 6
7 #include <stddef.h> 7 #include <stddef.h>
8 8
9 #include <algorithm> 9 #include <algorithm>
10 #include <cmath> 10 #include <cmath>
(...skipping 11 matching lines...) Expand all
22 #include "cc/tiles/prioritized_tile.h" 22 #include "cc/tiles/prioritized_tile.h"
23 #include "cc/tiles/tile.h" 23 #include "cc/tiles/tile.h"
24 #include "cc/tiles/tile_priority.h" 24 #include "cc/tiles/tile_priority.h"
25 #include "ui/gfx/geometry/point_conversions.h" 25 #include "ui/gfx/geometry/point_conversions.h"
26 #include "ui/gfx/geometry/rect_conversions.h" 26 #include "ui/gfx/geometry/rect_conversions.h"
27 #include "ui/gfx/geometry/rect_f.h" 27 #include "ui/gfx/geometry/rect_f.h"
28 #include "ui/gfx/geometry/safe_integer_conversions.h" 28 #include "ui/gfx/geometry/safe_integer_conversions.h"
29 #include "ui/gfx/geometry/size_conversions.h" 29 #include "ui/gfx/geometry/size_conversions.h"
30 30
31 namespace cc { 31 namespace cc {
32 namespace {
33
34 const float kSoonBorderDistanceViewportPercentage = 0.15f;
35 const float kMaxSoonBorderDistanceInScreenPixels = 312.f;
36
37 } // namespace
38
39 std::unique_ptr<PictureLayerTiling> PictureLayerTiling::Create(
40 WhichTree tree,
41 float contents_scale,
42 scoped_refptr<RasterSource> raster_source,
43 PictureLayerTilingClient* client,
44 size_t tiling_interest_area_padding,
45 float skewport_target_time_in_seconds,
46 int skewport_extrapolation_limit_in_content_pixels) {
47 return base::WrapUnique(new PictureLayerTiling(
48 tree, contents_scale, raster_source, client, tiling_interest_area_padding,
49 skewport_target_time_in_seconds,
50 skewport_extrapolation_limit_in_content_pixels));
51 }
52 32
53 PictureLayerTiling::PictureLayerTiling( 33 PictureLayerTiling::PictureLayerTiling(
54 WhichTree tree, 34 WhichTree tree,
55 float contents_scale, 35 float contents_scale,
56 scoped_refptr<RasterSource> raster_source, 36 scoped_refptr<RasterSource> raster_source,
57 PictureLayerTilingClient* client, 37 PictureLayerTilingClient* client)
58 size_t tiling_interest_area_padding, 38 : contents_scale_(contents_scale),
59 float skewport_target_time_in_seconds,
60 int skewport_extrapolation_limit_in_content_pixels)
61 : tiling_interest_area_padding_(tiling_interest_area_padding),
62 skewport_target_time_in_seconds_(skewport_target_time_in_seconds),
63 skewport_extrapolation_limit_in_content_pixels_(
64 skewport_extrapolation_limit_in_content_pixels),
65 contents_scale_(contents_scale),
66 client_(client), 39 client_(client),
67 tree_(tree), 40 tree_(tree),
68 raster_source_(raster_source), 41 raster_source_(raster_source),
69 resolution_(NON_IDEAL_RESOLUTION), 42 resolution_(NON_IDEAL_RESOLUTION),
70 may_contain_low_resolution_tiles_(false), 43 may_contain_low_resolution_tiles_(false),
71 tiling_data_(gfx::Size(), gfx::Size(), kBorderTexels), 44 tiling_data_(gfx::Size(), gfx::Size(), kBorderTexels),
72 can_require_tiles_for_activation_(false), 45 can_require_tiles_for_activation_(false),
73 current_content_to_screen_scale_(0.f), 46 current_content_to_screen_scale_(0.f),
74 has_visible_rect_tiles_(false), 47 has_visible_rect_tiles_(false),
75 has_skewport_rect_tiles_(false), 48 has_skewport_rect_tiles_(false),
76 has_soon_border_rect_tiles_(false), 49 has_soon_border_rect_tiles_(false),
77 has_eventually_rect_tiles_(false), 50 has_eventually_rect_tiles_(false),
78 all_tiles_done_(true), 51 all_tiles_done_(true) {
79 invalidated_since_last_compute_priority_rects_(false) {
80 DCHECK(!raster_source->IsSolidColor()); 52 DCHECK(!raster_source->IsSolidColor());
81 gfx::Size content_bounds = 53 gfx::Size content_bounds =
82 gfx::ScaleToCeiledSize(raster_source_->GetSize(), contents_scale); 54 gfx::ScaleToCeiledSize(raster_source_->GetSize(), contents_scale);
83 gfx::Size tile_size = client_->CalculateTileSize(content_bounds); 55 gfx::Size tile_size = client_->CalculateTileSize(content_bounds);
84 56
85 DCHECK(!gfx::ScaleToFlooredSize(raster_source_->GetSize(), contents_scale) 57 DCHECK(!gfx::ScaleToFlooredSize(raster_source_->GetSize(), contents_scale)
86 .IsEmpty()) 58 .IsEmpty())
87 << "Tiling created with scale too small as contents become empty." 59 << "Tiling created with scale too small as contents become empty."
88 << " Layer bounds: " << raster_source_->GetSize().ToString() 60 << " Layer bounds: " << raster_source_->GetSize().ToString()
89 << " Contents scale: " << contents_scale; 61 << " Contents scale: " << contents_scale;
90 62
91 tiling_data_.SetTilingSize(content_bounds); 63 tiling_data_.SetTilingSize(content_bounds);
92 tiling_data_.SetMaxTextureSize(tile_size); 64 tiling_data_.SetMaxTextureSize(tile_size);
93 } 65 }
94 66
95 PictureLayerTiling::~PictureLayerTiling() { 67 PictureLayerTiling::~PictureLayerTiling() {
96 } 68 }
97 69
98 // static
99 float PictureLayerTiling::CalculateSoonBorderDistance(
100 const gfx::Rect& visible_rect_in_content_space,
101 float content_to_screen_scale) {
102 float max_dimension = std::max(visible_rect_in_content_space.width(),
103 visible_rect_in_content_space.height());
104 return std::min(
105 kMaxSoonBorderDistanceInScreenPixels / content_to_screen_scale,
106 max_dimension * kSoonBorderDistanceViewportPercentage);
107 }
108
109 Tile* PictureLayerTiling::CreateTile(const Tile::CreateInfo& info) { 70 Tile* PictureLayerTiling::CreateTile(const Tile::CreateInfo& info) {
110 const int i = info.tiling_i_index; 71 const int i = info.tiling_i_index;
111 const int j = info.tiling_j_index; 72 const int j = info.tiling_j_index;
112 TileMapKey key(i, j); 73 TileMapKey key(i, j);
113 DCHECK(tiles_.find(key) == tiles_.end()); 74 DCHECK(tiles_.find(key) == tiles_.end());
114 75
115 if (!raster_source_->CoversRect(info.enclosing_layer_rect)) 76 if (!raster_source_->CoversRect(info.enclosing_layer_rect))
116 return nullptr; 77 return nullptr;
117 78
118 all_tiles_done_ = false; 79 all_tiles_done_ = false;
(...skipping 163 matching lines...) Expand 10 before | Expand all | Expand 10 after
282 for (int i = before_left; i <= before_right; ++i) { 243 for (int i = before_left; i <= before_right; ++i) {
283 Tile::CreateInfo info = CreateInfoForTile(i, after_bottom); 244 Tile::CreateInfo info = CreateInfoForTile(i, after_bottom);
284 if (ShouldCreateTileAt(info)) 245 if (ShouldCreateTileAt(info))
285 CreateTile(info); 246 CreateTile(info);
286 } 247 }
287 } 248 }
288 } 249 }
289 250
290 void PictureLayerTiling::Invalidate(const Region& layer_invalidation) { 251 void PictureLayerTiling::Invalidate(const Region& layer_invalidation) {
291 DCHECK(tree_ != ACTIVE_TREE || !client_->GetPendingOrActiveTwinTiling(this)); 252 DCHECK(tree_ != ACTIVE_TREE || !client_->GetPendingOrActiveTwinTiling(this));
292 invalidated_since_last_compute_priority_rects_ = true;
293 RemoveTilesInRegion(layer_invalidation, true /* recreate tiles */); 253 RemoveTilesInRegion(layer_invalidation, true /* recreate tiles */);
294 } 254 }
295 255
296 void PictureLayerTiling::RemoveTilesInRegion(const Region& layer_invalidation, 256 void PictureLayerTiling::RemoveTilesInRegion(const Region& layer_invalidation,
297 bool recreate_tiles) { 257 bool recreate_tiles) {
298 // We only invalidate the active tiling when it's orphaned: it has no pending 258 // We only invalidate the active tiling when it's orphaned: it has no pending
299 // twin, so it's slated for removal in the future. 259 // twin, so it's slated for removal in the future.
300 if (live_tiles_rect_.IsEmpty()) 260 if (live_tiles_rect_.IsEmpty())
301 return; 261 return;
302 // Pick 16 for the size of the SmallMap before it promotes to a unordered_map. 262 // Pick 16 for the size of the SmallMap before it promotes to a unordered_map.
(...skipping 265 matching lines...) Expand 10 before | Expand all | Expand 10 after
568 tiles_.erase(found); 528 tiles_.erase(found);
569 return true; 529 return true;
570 } 530 }
571 531
572 void PictureLayerTiling::Reset() { 532 void PictureLayerTiling::Reset() {
573 live_tiles_rect_ = gfx::Rect(); 533 live_tiles_rect_ = gfx::Rect();
574 tiles_.clear(); 534 tiles_.clear();
575 all_tiles_done_ = true; 535 all_tiles_done_ = true;
576 } 536 }
577 537
578 gfx::Rect PictureLayerTiling::ComputeSkewport( 538 void PictureLayerTiling::ComputeTilePriorityRects(
579 double current_frame_time_in_seconds, 539 const gfx::Rect& visible_rect_in_layer_space,
580 const gfx::Rect& visible_rect_in_content_space) const { 540 const gfx::Rect& skewport_in_layer_space,
581 gfx::Rect skewport = visible_rect_in_content_space; 541 const gfx::Rect& soon_border_rect_in_layer_space,
582 if (skewport.IsEmpty()) 542 const gfx::Rect& eventually_rect_in_layer_space,
583 return skewport;
584
585 if (visible_rect_history_[1].frame_time_in_seconds == 0.0)
586 return skewport;
587
588 double time_delta = current_frame_time_in_seconds -
589 visible_rect_history_[1].frame_time_in_seconds;
590 if (time_delta == 0.0)
591 return skewport;
592
593 double extrapolation_multiplier =
594 skewport_target_time_in_seconds_ / time_delta;
595
596 int old_x = visible_rect_history_[1].visible_rect_in_content_space.x();
597 int old_y = visible_rect_history_[1].visible_rect_in_content_space.y();
598 int old_right =
599 visible_rect_history_[1].visible_rect_in_content_space.right();
600 int old_bottom =
601 visible_rect_history_[1].visible_rect_in_content_space.bottom();
602
603 int new_x = visible_rect_in_content_space.x();
604 int new_y = visible_rect_in_content_space.y();
605 int new_right = visible_rect_in_content_space.right();
606 int new_bottom = visible_rect_in_content_space.bottom();
607
608 // Compute the maximum skewport based on
609 // |skewport_extrapolation_limit_in_content_pixels_|.
610 gfx::Rect max_skewport = skewport;
611 max_skewport.Inset(-skewport_extrapolation_limit_in_content_pixels_,
612 -skewport_extrapolation_limit_in_content_pixels_);
613
614 // Inset the skewport by the needed adjustment.
615 skewport.Inset(extrapolation_multiplier * (new_x - old_x),
616 extrapolation_multiplier * (new_y - old_y),
617 extrapolation_multiplier * (old_right - new_right),
618 extrapolation_multiplier * (old_bottom - new_bottom));
619
620 // Ensure that visible rect is contained in the skewport.
621 skewport.Union(visible_rect_in_content_space);
622
623 // Clip the skewport to |max_skewport|. This needs to happen after the
624 // union in case intersecting would have left the empty rect.
625 skewport.Intersect(max_skewport);
626
627 // Due to limits in int's representation, it is possible that the two
628 // operations above (union and intersect) result in an empty skewport. To
629 // avoid any unpleasant situations like that, union the visible rect again to
630 // ensure that skewport.Contains(visible_rect_in_content_space) is always
631 // true.
632 skewport.Union(visible_rect_in_content_space);
633
634 return skewport;
635 }
636
637 bool PictureLayerTiling::ComputeTilePriorityRects(
638 const gfx::Rect& viewport_in_layer_space,
639 float ideal_contents_scale, 543 float ideal_contents_scale,
640 double current_frame_time_in_seconds,
641 const Occlusion& occlusion_in_layer_space) { 544 const Occlusion& occlusion_in_layer_space) {
642 // If we have, or had occlusions, mark the tiles as 'not done' to ensure that 545 // If we have, or had occlusions, mark the tiles as 'not done' to ensure that
643 // we reiterate the tiles for rasterization. 546 // we reiterate the tiles for rasterization.
644 if (occlusion_in_layer_space.HasOcclusion() || 547 if (occlusion_in_layer_space.HasOcclusion() ||
645 current_occlusion_in_layer_space_.HasOcclusion()) { 548 current_occlusion_in_layer_space_.HasOcclusion()) {
646 set_all_tiles_done(false); 549 set_all_tiles_done(false);
647 } 550 }
648 551
649 bool invalidated = invalidated_since_last_compute_priority_rects_;
650 invalidated_since_last_compute_priority_rects_ = false;
651 if (!NeedsUpdateForFrameAtTimeAndViewport(current_frame_time_in_seconds,
652 viewport_in_layer_space)) {
653 // This should never be zero for the purposes of has_ever_been_updated().
654 DCHECK_NE(current_frame_time_in_seconds, 0.0);
655 return invalidated;
656 }
657
658 const float content_to_screen_scale = ideal_contents_scale / contents_scale_; 552 const float content_to_screen_scale = ideal_contents_scale / contents_scale_;
659 553
660 // We want to compute the visible rect and eventually rect from it in the 554 const gfx::Rect* input_rects[] = {
661 // space of the tiling. But the visible rect (viewport) can be arbitrarily 555 &visible_rect_in_layer_space, &skewport_in_layer_space,
662 // positioned, so be careful when scaling it since we can exceed integer 556 &soon_border_rect_in_layer_space, &eventually_rect_in_layer_space};
663 // bounds. 557 gfx::Rect output_rects[4];
664 gfx::Rect eventually_rect; 558 for (size_t i = 0; i < arraysize(input_rects); ++i) {
665 gfx::Rect visible_rect_in_content_space; 559 output_rects[i] = gfx::ToEnclosingRect(
560 gfx::ScaleRect(gfx::RectF(*input_rects[i]), contents_scale_));
561 }
562 // Make sure the eventually rect is aligned to tile bounds.
563 output_rects[3] =
564 tiling_data_.ExpandRectIgnoringBordersToTileBounds(output_rects[3]);
666 565
667 // We keep things as floats in here. 566 SetTilePriorityRects(content_to_screen_scale, output_rects[0],
668 { 567 output_rects[1], output_rects[2], output_rects[3],
669 gfx::RectF visible_rectf_in_content_space =
670 gfx::ScaleRect(gfx::RectF(viewport_in_layer_space), contents_scale_);
671
672 // Determine if the eventually rect will even touch the tiling, if it's too
673 // far away just treat it as empty so we don't exceed integer bounds.
674 const float pad_in_content_space =
675 tiling_interest_area_padding_ / content_to_screen_scale;
676 gfx::RectF eventually_rectf = visible_rectf_in_content_space;
677 // If the visible rect is empty, keep the eventually rect as empty.
678 if (!eventually_rectf.IsEmpty()) {
679 eventually_rectf.Inset(-pad_in_content_space, -pad_in_content_space);
680
681 // If the eventually rect will touch the tiling, then we convert back to
682 // integers and set the visible and eventually rects.
683 auto bounds = gfx::RectF(gfx::SizeF(tiling_size()));
684 if (eventually_rectf.Intersects(bounds)) {
685 visible_rect_in_content_space =
686 gfx::ToEnclosingRect(visible_rectf_in_content_space);
687 eventually_rect = gfx::ToEnclosingRect(eventually_rectf);
688 }
689 }
690 }
691 DCHECK_EQ(visible_rect_in_content_space.IsEmpty(), eventually_rect.IsEmpty());
692
693 // Now we have an empty visible/eventually rect if it's not useful and a
694 // non-empty one if it is. We can compute the final eventually rect.
695 eventually_rect =
696 tiling_data_.ExpandRectIgnoringBordersToTileBounds(eventually_rect);
697
698 DCHECK(eventually_rect.IsEmpty() ||
699 gfx::Rect(tiling_size()).Contains(eventually_rect))
700 << "tiling_size: " << tiling_size().ToString()
701 << " eventually_rect: " << eventually_rect.ToString();
702
703 if (tiling_size().IsEmpty()) {
704 UpdateVisibleRectHistory(current_frame_time_in_seconds,
705 visible_rect_in_content_space);
706 last_viewport_in_layer_space_ = viewport_in_layer_space;
707 return false;
708 }
709
710 // Calculate the skewport.
711 gfx::Rect skewport = ComputeSkewport(current_frame_time_in_seconds,
712 visible_rect_in_content_space);
713 DCHECK(skewport.Contains(visible_rect_in_content_space));
714
715 // Calculate the soon border rect.
716 gfx::Rect soon_border_rect = visible_rect_in_content_space;
717 float border = CalculateSoonBorderDistance(visible_rect_in_content_space,
718 content_to_screen_scale);
719 soon_border_rect.Inset(-border, -border, -border, -border);
720
721 UpdateVisibleRectHistory(current_frame_time_in_seconds,
722 visible_rect_in_content_space);
723 last_viewport_in_layer_space_ = viewport_in_layer_space;
724
725 SetTilePriorityRects(content_to_screen_scale, visible_rect_in_content_space,
726 skewport, soon_border_rect, eventually_rect,
727 occlusion_in_layer_space); 568 occlusion_in_layer_space);
728 SetLiveTilesRect(eventually_rect); 569 SetLiveTilesRect(output_rects[3]);
729 return true;
730 } 570 }
731 571
732 void PictureLayerTiling::SetTilePriorityRects( 572 void PictureLayerTiling::SetTilePriorityRects(
733 float content_to_screen_scale, 573 float content_to_screen_scale,
734 const gfx::Rect& visible_rect_in_content_space, 574 const gfx::Rect& visible_rect_in_content_space,
735 const gfx::Rect& skewport, 575 const gfx::Rect& skewport,
736 const gfx::Rect& soon_border_rect, 576 const gfx::Rect& soon_border_rect,
737 const gfx::Rect& eventually_rect, 577 const gfx::Rect& eventually_rect,
738 const Occlusion& occlusion_in_layer_space) { 578 const Occlusion& occlusion_in_layer_space) {
739 current_visible_rect_ = visible_rect_in_content_space; 579 current_visible_rect_ = visible_rect_in_content_space;
(...skipping 299 matching lines...) Expand 10 before | Expand all | Expand 10 after
1039 size_t PictureLayerTiling::GPUMemoryUsageInBytes() const { 879 size_t PictureLayerTiling::GPUMemoryUsageInBytes() const {
1040 size_t amount = 0; 880 size_t amount = 0;
1041 for (TileMap::const_iterator it = tiles_.begin(); it != tiles_.end(); ++it) { 881 for (TileMap::const_iterator it = tiles_.begin(); it != tiles_.end(); ++it) {
1042 const Tile* tile = it->second.get(); 882 const Tile* tile = it->second.get();
1043 amount += tile->GPUMemoryUsageInBytes(); 883 amount += tile->GPUMemoryUsageInBytes();
1044 } 884 }
1045 return amount; 885 return amount;
1046 } 886 }
1047 887
1048 } // namespace cc 888 } // namespace cc
OLDNEW
« no previous file with comments | « cc/tiles/picture_layer_tiling.h ('k') | cc/tiles/picture_layer_tiling_perftest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698