12a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Copyright 2012 The Chromium Authors. All rights reserved. 22a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be 32a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// found in the LICENSE file. 42a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 5c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "cc/resources/picture_pile.h" 6c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 72a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include <algorithm> 84e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#include <limits> 9c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include <vector> 102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "cc/base/region.h" 124e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#include "cc/debug/rendering_stats_instrumentation.h" 132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "cc/resources/picture_pile_impl.h" 145d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "cc/resources/raster_worker_pool.h" 15a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)#include "cc/resources/tile_priority.h" 162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)namespace { 182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Layout pixel buffer around the visible layer rect to record. Any base 192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// picture that intersects the visible layer rect expanded by this distance 202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// will be recorded. 212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)const int kPixelDistanceToRecord = 8000; 221320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci// We don't perform solid color analysis on images that have more than 10 skia 231320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci// operations. 241320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucciconst int kOpCountThatIsOkToAnalyze = 10; 25f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 26f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)// TODO(humper): The density threshold here is somewhat arbitrary; need a 27f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)// way to set // this from the command line so we can write a benchmark 28f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)// script and find a sweet spot. 29f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)const float kDensityThreshold = 0.5f; 30f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 31116680a4aac90f2aa7413d9095a592090648e557Ben Murdochbool rect_sort_y(const gfx::Rect& r1, const gfx::Rect& r2) { 32f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) return r1.y() < r2.y() || (r1.y() == r2.y() && r1.x() < r2.x()); 33f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)} 34f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 35116680a4aac90f2aa7413d9095a592090648e557Ben Murdochbool rect_sort_x(const gfx::Rect& r1, const gfx::Rect& r2) { 36f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) return r1.x() < r2.x() || (r1.x() == r2.x() && r1.y() < r2.y()); 37f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)} 38f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 39116680a4aac90f2aa7413d9095a592090648e557Ben Murdochfloat PerformClustering(const std::vector<gfx::Rect>& tiles, 40116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch std::vector<gfx::Rect>* clustered_rects) { 41f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // These variables track the record area and invalid area 42f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // for the entire clustering 43f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) int total_record_area = 0; 44f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) int total_invalid_area = 0; 45f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 46f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // These variables track the record area and invalid area 47f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // for the current cluster being constructed. 48f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) gfx::Rect cur_record_rect; 49f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) int cluster_record_area = 0, cluster_invalid_area = 0; 50f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 51f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) for (std::vector<gfx::Rect>::const_iterator it = tiles.begin(); 52f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) it != tiles.end(); 53f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) it++) { 54f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) gfx::Rect invalid_tile = *it; 55f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 56f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // For each tile, we consider adding the invalid tile to the 57f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // current record rectangle. Only add it if the amount of empty 58f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // space created is below a density threshold. 59f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) int tile_area = invalid_tile.width() * invalid_tile.height(); 60f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 61f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) gfx::Rect proposed_union = cur_record_rect; 62f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) proposed_union.Union(invalid_tile); 63f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) int proposed_area = proposed_union.width() * proposed_union.height(); 64f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) float proposed_density = 65f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) static_cast<float>(cluster_invalid_area + tile_area) / 66f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) static_cast<float>(proposed_area); 67f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 68f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) if (proposed_density >= kDensityThreshold) { 69f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // It's okay to add this invalid tile to the 70f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // current recording rectangle. 71f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) cur_record_rect = proposed_union; 72f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) cluster_record_area = proposed_area; 73f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) cluster_invalid_area += tile_area; 74f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) total_invalid_area += tile_area; 75f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) } else { 76f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // Adding this invalid tile to the current recording rectangle 77f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // would exceed our badness threshold, so put the current rectangle 78f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // in the list of recording rects, and start a new one. 79f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) clustered_rects->push_back(cur_record_rect); 80f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) total_record_area += cluster_record_area; 81f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) cur_record_rect = invalid_tile; 82f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) cluster_invalid_area = tile_area; 83f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) cluster_record_area = tile_area; 84f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) } 85f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) } 86f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 87f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) DCHECK(!cur_record_rect.IsEmpty()); 88f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) clustered_rects->push_back(cur_record_rect); 89f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) total_record_area += cluster_record_area;; 90f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 91f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) DCHECK_NE(total_record_area, 0); 92f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 93f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) return static_cast<float>(total_invalid_area) / 94f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) static_cast<float>(total_record_area); 95116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch} 96f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 97f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)float ClusterTiles(const std::vector<gfx::Rect>& invalid_tiles, 98f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) std::vector<gfx::Rect>* record_rects) { 99f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) TRACE_EVENT1("cc", "ClusterTiles", 100f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) "count", 101f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) invalid_tiles.size()); 102f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 103f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) if (invalid_tiles.size() <= 1) { 104f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // Quickly handle the special case for common 105f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // single-invalidation update, and also the less common 106f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // case of no tiles passed in. 107f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) *record_rects = invalid_tiles; 108f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) return 1; 109f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) } 110f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 111f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // Sort the invalid tiles by y coordinate. 112f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) std::vector<gfx::Rect> invalid_tiles_vertical = invalid_tiles; 113f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) std::sort(invalid_tiles_vertical.begin(), 114f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) invalid_tiles_vertical.end(), 115f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) rect_sort_y); 116f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 117f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) float vertical_density; 118f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) std::vector<gfx::Rect> vertical_clustering; 119116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch vertical_density = PerformClustering(invalid_tiles_vertical, 120116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch &vertical_clustering); 121116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 122116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch // If vertical density is optimal, then we can return early. 123116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch if (vertical_density == 1.f) { 124116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch *record_rects = vertical_clustering; 125116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch return vertical_density; 126116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch } 127f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 128f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // Now try again with a horizontal sort, see which one is best 129f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) std::vector<gfx::Rect> invalid_tiles_horizontal = invalid_tiles; 130116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch std::sort(invalid_tiles_horizontal.begin(), 131116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch invalid_tiles_horizontal.end(), 132f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) rect_sort_x); 133f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 134f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) float horizontal_density; 135f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) std::vector<gfx::Rect> horizontal_clustering; 136116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch horizontal_density = PerformClustering(invalid_tiles_horizontal, 137116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch &horizontal_clustering); 138f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 139f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) if (vertical_density < horizontal_density) { 140f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) *record_rects = horizontal_clustering; 141f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) return horizontal_density; 142f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) } 143f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 144f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) *record_rects = vertical_clustering; 145f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) return vertical_density; 146f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)} 147f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 1487dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch} // namespace 1492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)namespace cc { 1512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1525b62eb5758cb7b791cfdd45cf78f35dc060631b6Ben MurdochPicturePile::PicturePile() 1535b62eb5758cb7b791cfdd45cf78f35dc060631b6Ben Murdoch : is_suitable_for_gpu_rasterization_(true), 1545b62eb5758cb7b791cfdd45cf78f35dc060631b6Ben Murdoch pixel_record_distance_(kPixelDistanceToRecord) { 1551320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci} 1562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)PicturePile::~PicturePile() { 1582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 1592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 160f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)bool PicturePile::UpdateAndExpandInvalidation( 161f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) ContentLayerClient* painter, 162f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) Region* invalidation, 163f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) SkColor background_color, 164f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) bool contents_opaque, 165f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) bool contents_fill_bounds_completely, 166116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch const gfx::Size& layer_size, 167f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) const gfx::Rect& visible_layer_rect, 168f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) int frame_number, 169f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) Picture::RecordingMode recording_mode, 170f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) RenderingStatsInstrumentation* stats_instrumentation) { 1712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) background_color_ = background_color; 172868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) contents_opaque_ = contents_opaque; 173effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch contents_fill_bounds_completely_ = contents_fill_bounds_completely; 1742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 175116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch bool updated = false; 176116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 177116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch Region resize_invalidation; 178116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch gfx::Size old_tiling_size = tiling_size(); 179116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch if (old_tiling_size != layer_size) { 180116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch tiling_.SetTilingSize(layer_size); 181116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch updated = true; 182116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch } 183116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 1842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) gfx::Rect interest_rect = visible_layer_rect; 1855b62eb5758cb7b791cfdd45cf78f35dc060631b6Ben Murdoch interest_rect.Inset(-pixel_record_distance_, -pixel_record_distance_); 18623730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) recorded_viewport_ = interest_rect; 187116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch recorded_viewport_.Intersect(gfx::Rect(tiling_size())); 1881e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) 189f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) gfx::Rect interest_rect_over_tiles = 190f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) tiling_.ExpandRectToTileBounds(interest_rect); 191f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) 192757e6d30528497c763bce864b552885d3c119fc7enne gfx::Size min_tiling_size( 193757e6d30528497c763bce864b552885d3c119fc7enne std::min(tiling_size().width(), old_tiling_size.width()), 194757e6d30528497c763bce864b552885d3c119fc7enne std::min(tiling_size().height(), old_tiling_size.height())); 195757e6d30528497c763bce864b552885d3c119fc7enne gfx::Size max_tiling_size( 196757e6d30528497c763bce864b552885d3c119fc7enne std::max(tiling_size().width(), old_tiling_size.width()), 197757e6d30528497c763bce864b552885d3c119fc7enne std::max(tiling_size().height(), old_tiling_size.height())); 198757e6d30528497c763bce864b552885d3c119fc7enne 199116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch if (old_tiling_size != layer_size) { 200116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch has_any_recordings_ = false; 201f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) 202757e6d30528497c763bce864b552885d3c119fc7enne // Drop recordings that are outside the new or old layer bounds or that 203757e6d30528497c763bce864b552885d3c119fc7enne // changed size. Newly exposed areas are considered invalidated. 204757e6d30528497c763bce864b552885d3c119fc7enne // Previously exposed areas that are now outside of bounds also need to 205757e6d30528497c763bce864b552885d3c119fc7enne // be invalidated, as they may become part of raster when scale < 1. 206116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch std::vector<PictureMapKey> to_erase; 207116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch int min_toss_x = tiling_.num_tiles_x(); 208757e6d30528497c763bce864b552885d3c119fc7enne if (max_tiling_size.width() > min_tiling_size.width()) { 209116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch min_toss_x = 210757e6d30528497c763bce864b552885d3c119fc7enne tiling_.FirstBorderTileXIndexFromSrcCoord(min_tiling_size.width()); 211116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch } 212116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch int min_toss_y = tiling_.num_tiles_y(); 213757e6d30528497c763bce864b552885d3c119fc7enne if (max_tiling_size.height() > min_tiling_size.height()) { 214116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch min_toss_y = 215757e6d30528497c763bce864b552885d3c119fc7enne tiling_.FirstBorderTileYIndexFromSrcCoord(min_tiling_size.height()); 216116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch } 217116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch for (PictureMap::const_iterator it = picture_map_.begin(); 218116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch it != picture_map_.end(); 219116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch ++it) { 220116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch const PictureMapKey& key = it->first; 221116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch if (key.first < min_toss_x && key.second < min_toss_y) { 222116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch has_any_recordings_ |= !!it->second.GetPicture(); 223116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch continue; 224116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch } 225116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch to_erase.push_back(key); 226116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch } 227116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 228116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch for (size_t i = 0; i < to_erase.size(); ++i) 229116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch picture_map_.erase(to_erase[i]); 230116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 231116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch // If a recording is dropped and not re-recorded below, invalidate that 232116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch // full recording to cause any raster tiles that would use it to be 233116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch // dropped. 234757e6d30528497c763bce864b552885d3c119fc7enne // If the recording will be replaced below, invalidate newly exposed 235757e6d30528497c763bce864b552885d3c119fc7enne // areas and previously exposed areas to force raster tiles that include the 236757e6d30528497c763bce864b552885d3c119fc7enne // old recording to know there is new recording to display. 237757e6d30528497c763bce864b552885d3c119fc7enne gfx::Rect min_tiling_rect_over_tiles = 238757e6d30528497c763bce864b552885d3c119fc7enne tiling_.ExpandRectToTileBounds(gfx::Rect(min_tiling_size)); 239116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch if (min_toss_x < tiling_.num_tiles_x()) { 2401320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci // The bounds which we want to invalidate are the tiles along the old 241757e6d30528497c763bce864b552885d3c119fc7enne // edge of the pile when expanding, or the new edge of the pile when 242757e6d30528497c763bce864b552885d3c119fc7enne // shrinking. In either case, it's the difference of the two, so we'll 243757e6d30528497c763bce864b552885d3c119fc7enne // call this bounding box the DELTA EDGE RECT. 2441320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci // 245757e6d30528497c763bce864b552885d3c119fc7enne // In the picture below, the delta edge rect would be the bounding box of 246757e6d30528497c763bce864b552885d3c119fc7enne // tiles {h,i,j}. |min_toss_x| would be equal to the horizontal index of 247757e6d30528497c763bce864b552885d3c119fc7enne // the same tiles. 2481320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci // 249757e6d30528497c763bce864b552885d3c119fc7enne // min pile edge-v max pile edge-v 2501320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci // ---------------+ - - - - - - - -+ 2511320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci // mmppssvvyybbeeh|h . 2521320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci // mmppssvvyybbeeh|h . 2531320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci // nnqqttwwzzccffi|i . 2541320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci // nnqqttwwzzccffi|i . 2551320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci // oorruuxxaaddggj|j . 2561320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci // oorruuxxaaddggj|j . 257757e6d30528497c763bce864b552885d3c119fc7enne // ---------------+ - - - - - - - -+ <- min pile edge 2581320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci // . 259757e6d30528497c763bce864b552885d3c119fc7enne // - - - - - - - - - - - - - - - -+ <- max pile edge 2601320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci // 2611320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci // If you were to slide a vertical beam from the left edge of the 262757e6d30528497c763bce864b552885d3c119fc7enne // delta edge rect toward the right, it would either hit the right edge 263757e6d30528497c763bce864b552885d3c119fc7enne // of the delta edge rect, or the interest rect (expanded to the bounds 2641320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci // of the tiles it touches). The same is true for a beam parallel to 265757e6d30528497c763bce864b552885d3c119fc7enne // any of the four edges, sliding across the delta edge rect. We use 2661320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci // the union of these four rectangles generated by these beams to 267757e6d30528497c763bce864b552885d3c119fc7enne // determine which part of the delta edge rect is outside of the expanded 2681320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci // interest rect. 2691320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci // 270757e6d30528497c763bce864b552885d3c119fc7enne // Case 1: Intersect rect is outside the delta edge rect. It can be 2711320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci // either on the left or the right. The |left_rect| and |right_rect|, 2721320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci // cover this case, one will be empty and one will cover the full 273757e6d30528497c763bce864b552885d3c119fc7enne // delta edge rect. In the picture below, |left_rect| would cover the 274757e6d30528497c763bce864b552885d3c119fc7enne // delta edge rect, and |right_rect| would be empty. 2751320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci // +----------------------+ |^^^^^^^^^^^^^^^| 276757e6d30528497c763bce864b552885d3c119fc7enne // |===> DELTA EDGE RECT | | | 2771320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci // |===> | | INTEREST RECT | 2781320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci // |===> | | | 2791320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci // |===> | | | 2801320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci // +----------------------+ |vvvvvvvvvvvvvvv| 2811320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci // 282757e6d30528497c763bce864b552885d3c119fc7enne // Case 2: Interest rect is inside the delta edge rect. It will always 283757e6d30528497c763bce864b552885d3c119fc7enne // fill the entire delta edge rect horizontally since the old edge rect 2841320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci // is a single tile wide, and the interest rect has been expanded to the 2851320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci // bounds of the tiles it touches. In this case the |left_rect| and 2861320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci // |right_rect| will be empty, but the case is handled by the |top_rect| 2871320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci // and |bottom_rect|. In the picture below, neither the |top_rect| nor 2881320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci // |bottom_rect| would empty, they would each cover the area of the old 2891320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci // edge rect outside the expanded interest rect. 2901320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci // +-----------------+ 2911320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci // |:::::::::::::::::| 2921320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci // |:::::::::::::::::| 2931320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci // |vvvvvvvvvvvvvvvvv| 2941320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci // | | 2951320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci // +-----------------+ 2961320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci // | INTEREST RECT | 2971320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci // | | 2981320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci // +-----------------+ 2991320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci // | | 300757e6d30528497c763bce864b552885d3c119fc7enne // | DELTA EDGE RECT | 3011320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci // +-----------------+ 3021320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci // 3031320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci // Lastly, we need to consider tiles inside the expanded interest rect. 3041320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci // For those tiles, we want to invalidate exactly the newly exposed 305757e6d30528497c763bce864b552885d3c119fc7enne // pixels. In the picture below the tiles in the delta edge rect have 306757e6d30528497c763bce864b552885d3c119fc7enne // been resized and the area covered by periods must be invalidated. The 3071320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci // |exposed_rect| will cover exactly that area. 308757e6d30528497c763bce864b552885d3c119fc7enne // v-min pile edge 3091320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci // +---------+-------+ 3101320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci // | ........| 3111320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci // | ........| 312757e6d30528497c763bce864b552885d3c119fc7enne // | DELTA EDGE.RECT.| 3131320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci // | ........| 3141320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci // | ........| 3151320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci // | ........| 3161320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci // | ........| 3171320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci // | ........| 3181320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci // | ........| 3191320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci // +---------+-------+ 3201320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 3211320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci int left = tiling_.TilePositionX(min_toss_x); 3221320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci int right = left + tiling_.TileSizeX(min_toss_x); 323757e6d30528497c763bce864b552885d3c119fc7enne int top = min_tiling_rect_over_tiles.y(); 324757e6d30528497c763bce864b552885d3c119fc7enne int bottom = min_tiling_rect_over_tiles.bottom(); 3251320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 3261320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci int left_until = std::min(interest_rect_over_tiles.x(), right); 3271320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci int right_until = std::max(interest_rect_over_tiles.right(), left); 3281320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci int top_until = std::min(interest_rect_over_tiles.y(), bottom); 3291320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci int bottom_until = std::max(interest_rect_over_tiles.bottom(), top); 3301320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 331757e6d30528497c763bce864b552885d3c119fc7enne int exposed_left = min_tiling_size.width(); 332757e6d30528497c763bce864b552885d3c119fc7enne int exposed_left_until = max_tiling_size.width(); 3331320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci int exposed_top = top; 334757e6d30528497c763bce864b552885d3c119fc7enne int exposed_bottom = max_tiling_size.height(); 3351320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci DCHECK_GE(exposed_left, left); 3361320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 3371320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci gfx::Rect left_rect(left, top, left_until - left, bottom - top); 3381320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci gfx::Rect right_rect(right_until, top, right - right_until, bottom - top); 3391320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci gfx::Rect top_rect(left, top, right - left, top_until - top); 3401320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci gfx::Rect bottom_rect( 3411320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci left, bottom_until, right - left, bottom - bottom_until); 3421320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci gfx::Rect exposed_rect(exposed_left, 3431320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci exposed_top, 3441320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci exposed_left_until - exposed_left, 3451320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci exposed_bottom - exposed_top); 3461320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci resize_invalidation.Union(left_rect); 3471320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci resize_invalidation.Union(right_rect); 3481320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci resize_invalidation.Union(top_rect); 3491320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci resize_invalidation.Union(bottom_rect); 3501320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci resize_invalidation.Union(exposed_rect); 351116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch } 352116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch if (min_toss_y < tiling_.num_tiles_y()) { 3531320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci // The same thing occurs here as in the case above, but the invalidation 354757e6d30528497c763bce864b552885d3c119fc7enne // rect is the bounding box around the bottom row of tiles in the min 3551320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci // pile. This would be tiles {o,r,u,x,a,d,g,j} in the above picture. 3561320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 3571320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci int top = tiling_.TilePositionY(min_toss_y); 3581320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci int bottom = top + tiling_.TileSizeY(min_toss_y); 359757e6d30528497c763bce864b552885d3c119fc7enne int left = min_tiling_rect_over_tiles.x(); 360757e6d30528497c763bce864b552885d3c119fc7enne int right = min_tiling_rect_over_tiles.right(); 3611320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 3621320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci int top_until = std::min(interest_rect_over_tiles.y(), bottom); 3631320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci int bottom_until = std::max(interest_rect_over_tiles.bottom(), top); 3641320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci int left_until = std::min(interest_rect_over_tiles.x(), right); 3651320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci int right_until = std::max(interest_rect_over_tiles.right(), left); 3661320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 367757e6d30528497c763bce864b552885d3c119fc7enne int exposed_top = min_tiling_size.height(); 368757e6d30528497c763bce864b552885d3c119fc7enne int exposed_top_until = max_tiling_size.height(); 3691320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci int exposed_left = left; 370757e6d30528497c763bce864b552885d3c119fc7enne int exposed_right = max_tiling_size.width(); 3711320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci DCHECK_GE(exposed_top, top); 3721320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 3731320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci gfx::Rect left_rect(left, top, left_until - left, bottom - top); 3741320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci gfx::Rect right_rect(right_until, top, right - right_until, bottom - top); 3751320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci gfx::Rect top_rect(left, top, right - left, top_until - top); 3761320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci gfx::Rect bottom_rect( 3771320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci left, bottom_until, right - left, bottom - bottom_until); 3781320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci gfx::Rect exposed_rect(exposed_left, 3791320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci exposed_top, 3801320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci exposed_right - exposed_left, 3811320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci exposed_top_until - exposed_top); 3821320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci resize_invalidation.Union(left_rect); 3831320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci resize_invalidation.Union(right_rect); 3841320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci resize_invalidation.Union(top_rect); 3851320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci resize_invalidation.Union(bottom_rect); 3861320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci resize_invalidation.Union(exposed_rect); 387116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch } 388116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch } 389116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 3901675a649fd7a8b3cb80ffddae2dc181f122353c5Ben Murdoch // Detect cases where the full pile is invalidated, in this situation we 3911675a649fd7a8b3cb80ffddae2dc181f122353c5Ben Murdoch // can just drop/invalidate everything. 3921675a649fd7a8b3cb80ffddae2dc181f122353c5Ben Murdoch if (invalidation->Contains(gfx::Rect(old_tiling_size)) || 3931675a649fd7a8b3cb80ffddae2dc181f122353c5Ben Murdoch invalidation->Contains(gfx::Rect(tiling_size()))) { 3941675a649fd7a8b3cb80ffddae2dc181f122353c5Ben Murdoch for (auto& it : picture_map_) 3951675a649fd7a8b3cb80ffddae2dc181f122353c5Ben Murdoch updated = it.second.Invalidate(frame_number) || updated; 3961675a649fd7a8b3cb80ffddae2dc181f122353c5Ben Murdoch } else { 3975b62eb5758cb7b791cfdd45cf78f35dc060631b6Ben Murdoch // Expand invalidation that is on tiles that aren't in the interest rect and 3985b62eb5758cb7b791cfdd45cf78f35dc060631b6Ben Murdoch // will not be re-recorded below. These tiles are no longer valid and should 3995b62eb5758cb7b791cfdd45cf78f35dc060631b6Ben Murdoch // be considerered fully invalid, so we can know to not keep around raster 4005b62eb5758cb7b791cfdd45cf78f35dc060631b6Ben Murdoch // tiles that intersect with these recording tiles. 4011675a649fd7a8b3cb80ffddae2dc181f122353c5Ben Murdoch Region invalidation_expanded_to_full_tiles; 4021675a649fd7a8b3cb80ffddae2dc181f122353c5Ben Murdoch 4031675a649fd7a8b3cb80ffddae2dc181f122353c5Ben Murdoch for (Region::Iterator i(*invalidation); i.has_rect(); i.next()) { 4041675a649fd7a8b3cb80ffddae2dc181f122353c5Ben Murdoch gfx::Rect invalid_rect = i.rect(); 4051675a649fd7a8b3cb80ffddae2dc181f122353c5Ben Murdoch 4065b62eb5758cb7b791cfdd45cf78f35dc060631b6Ben Murdoch // This rect covers the bounds (excluding borders) of all tiles whose 4075b62eb5758cb7b791cfdd45cf78f35dc060631b6Ben Murdoch // bounds (including borders) touch the |interest_rect|. This matches 4085b62eb5758cb7b791cfdd45cf78f35dc060631b6Ben Murdoch // the iteration of the |invalid_rect| below which includes borders when 4095b62eb5758cb7b791cfdd45cf78f35dc060631b6Ben Murdoch // calling Invalidate() on pictures. 4105b62eb5758cb7b791cfdd45cf78f35dc060631b6Ben Murdoch gfx::Rect invalid_rect_outside_interest_rect_tiles = 4115b62eb5758cb7b791cfdd45cf78f35dc060631b6Ben Murdoch tiling_.ExpandRectToTileBounds(invalid_rect); 4125b62eb5758cb7b791cfdd45cf78f35dc060631b6Ben Murdoch // We subtract the |interest_rect_over_tiles| which represents the bounds 4135b62eb5758cb7b791cfdd45cf78f35dc060631b6Ben Murdoch // of tiles that will be re-recorded below. This matches the iteration of 4145b62eb5758cb7b791cfdd45cf78f35dc060631b6Ben Murdoch // |interest_rect| below which includes borders. 4151675a649fd7a8b3cb80ffddae2dc181f122353c5Ben Murdoch // TODO(danakj): We should have a Rect-subtract-Rect-to-2-rects operator 4161675a649fd7a8b3cb80ffddae2dc181f122353c5Ben Murdoch // instead of using Rect::Subtract which gives you the bounding box of the 4171675a649fd7a8b3cb80ffddae2dc181f122353c5Ben Murdoch // subtraction. 4181675a649fd7a8b3cb80ffddae2dc181f122353c5Ben Murdoch invalid_rect_outside_interest_rect_tiles.Subtract( 4191675a649fd7a8b3cb80ffddae2dc181f122353c5Ben Murdoch interest_rect_over_tiles); 4205b62eb5758cb7b791cfdd45cf78f35dc060631b6Ben Murdoch invalidation_expanded_to_full_tiles.Union( 4215b62eb5758cb7b791cfdd45cf78f35dc060631b6Ben Murdoch invalid_rect_outside_interest_rect_tiles); 4221675a649fd7a8b3cb80ffddae2dc181f122353c5Ben Murdoch 4231675a649fd7a8b3cb80ffddae2dc181f122353c5Ben Murdoch // Split this inflated invalidation across tile boundaries and apply it 4241675a649fd7a8b3cb80ffddae2dc181f122353c5Ben Murdoch // to all tiles that it touches. 4251675a649fd7a8b3cb80ffddae2dc181f122353c5Ben Murdoch bool include_borders = true; 4261675a649fd7a8b3cb80ffddae2dc181f122353c5Ben Murdoch for (TilingData::Iterator iter(&tiling_, invalid_rect, include_borders); 4271675a649fd7a8b3cb80ffddae2dc181f122353c5Ben Murdoch iter; 4281675a649fd7a8b3cb80ffddae2dc181f122353c5Ben Murdoch ++iter) { 4291675a649fd7a8b3cb80ffddae2dc181f122353c5Ben Murdoch const PictureMapKey& key = iter.index(); 4301675a649fd7a8b3cb80ffddae2dc181f122353c5Ben Murdoch 4311675a649fd7a8b3cb80ffddae2dc181f122353c5Ben Murdoch PictureMap::iterator picture_it = picture_map_.find(key); 4321675a649fd7a8b3cb80ffddae2dc181f122353c5Ben Murdoch if (picture_it == picture_map_.end()) 4331675a649fd7a8b3cb80ffddae2dc181f122353c5Ben Murdoch continue; 4341675a649fd7a8b3cb80ffddae2dc181f122353c5Ben Murdoch 4351675a649fd7a8b3cb80ffddae2dc181f122353c5Ben Murdoch // Inform the grid cell that it has been invalidated in this frame. 4361675a649fd7a8b3cb80ffddae2dc181f122353c5Ben Murdoch updated = picture_it->second.Invalidate(frame_number) || updated; 4371675a649fd7a8b3cb80ffddae2dc181f122353c5Ben Murdoch // Invalidate drops the picture so the whole tile better be invalidated 4381675a649fd7a8b3cb80ffddae2dc181f122353c5Ben Murdoch // if it won't be re-recorded below. 4391675a649fd7a8b3cb80ffddae2dc181f122353c5Ben Murdoch DCHECK(tiling_.TileBounds(key.first, key.second) 4401675a649fd7a8b3cb80ffddae2dc181f122353c5Ben Murdoch .Intersects(interest_rect_over_tiles) || 4411675a649fd7a8b3cb80ffddae2dc181f122353c5Ben Murdoch invalidation_expanded_to_full_tiles.Contains( 4421675a649fd7a8b3cb80ffddae2dc181f122353c5Ben Murdoch tiling_.TileBounds(key.first, key.second))); 4431675a649fd7a8b3cb80ffddae2dc181f122353c5Ben Murdoch } 4442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 4451675a649fd7a8b3cb80ffddae2dc181f122353c5Ben Murdoch invalidation->Union(invalidation_expanded_to_full_tiles); 4461e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) } 4472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 448116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch invalidation->Union(resize_invalidation); 449f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) 450f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // Make a list of all invalid tiles; we will attempt to 451f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // cluster these into multiple invalidation regions. 452f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) std::vector<gfx::Rect> invalid_tiles; 45323730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) bool include_borders = true; 45423730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) for (TilingData::Iterator it(&tiling_, interest_rect, include_borders); it; 45523730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) ++it) { 4561e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) const PictureMapKey& key = it.index(); 457a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) PictureInfo& info = picture_map_[key]; 458a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) 459a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) gfx::Rect rect = PaddedRect(key); 460a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) int distance_to_visible = 461a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) rect.ManhattanInternalDistance(visible_layer_rect); 462a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) 463a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) if (info.NeedsRecording(frame_number, distance_to_visible)) { 464f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) gfx::Rect tile = tiling_.TileBounds(key.first, key.second); 465f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) invalid_tiles.push_back(tile); 466f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) } else if (!info.GetPicture()) { 467f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) if (recorded_viewport_.Intersects(rect)) { 468f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) // Recorded viewport is just an optimization for a fully recorded 469f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) // interest rect. In this case, a tile in that rect has declined 470f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) // to be recorded (probably due to frequent invalidations). 471f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) // TODO(enne): Shrink the recorded_viewport_ rather than clearing. 472f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) recorded_viewport_ = gfx::Rect(); 473f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) } 474f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) 475f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) // If a tile in the interest rect is not recorded, the entire tile needs 476f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) // to be considered invalid, so that we know not to keep around raster 477f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) // tiles that intersect this recording tile. 478f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) invalidation->Union(tiling_.TileBounds(it.index_x(), it.index_y())); 4792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 4802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 4812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 482f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) std::vector<gfx::Rect> record_rects; 483f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) ClusterTiles(invalid_tiles, &record_rects); 484f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 48523730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) if (record_rects.empty()) 486116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch return updated; 4872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 488f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) for (std::vector<gfx::Rect>::iterator it = record_rects.begin(); 489f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) it != record_rects.end(); 490f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) it++) { 491f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) gfx::Rect record_rect = *it; 492f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) record_rect = PadRect(record_rect); 493f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 494f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) int repeat_count = std::max(1, slow_down_raster_scale_factor_for_debug_); 4955d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) scoped_refptr<Picture> picture; 4965d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 4975d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // Note: Currently, gathering of pixel refs when using a single 4985d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // raster thread doesn't provide any benefit. This might change 4995d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // in the future but we avoid it for now to reduce the cost of 5005d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // Picture::Create. 50103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) bool gather_pixel_refs = RasterWorkerPool::GetNumRasterThreads() > 1; 502f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 503f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) { 504a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) base::TimeDelta best_duration = base::TimeDelta::Max(); 505f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) for (int i = 0; i < repeat_count; i++) { 506f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) base::TimeTicks start_time = stats_instrumentation->StartRecording(); 5075d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) picture = Picture::Create(record_rect, 5085d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) painter, 5095d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) tile_grid_info_, 5105d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) gather_pixel_refs, 511010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) recording_mode); 512a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch // Note the '&&' with previous is-suitable state. 513a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch // This means that once a picture-pile becomes unsuitable for gpu 514a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch // rasterization due to some content, it will continue to be unsuitable 515a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch // even if that content is replaced by gpu-friendly content. 516a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch // This is an optimization to avoid iterating though all pictures in 517a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch // the pile after each invalidation. 518a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch is_suitable_for_gpu_rasterization_ &= 519a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch picture->IsSuitableForGpuRasterization(); 52003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) has_text_ |= picture->HasText(); 521f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) base::TimeDelta duration = 522f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) stats_instrumentation->EndRecording(start_time); 523f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) best_duration = std::min(duration, best_duration); 524f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) } 525f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) int recorded_pixel_count = 526f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) picture->LayerRect().width() * picture->LayerRect().height(); 527f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) stats_instrumentation->AddRecord(best_duration, recorded_pixel_count); 5281e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) } 5292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 53023730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) bool found_tile_for_recorded_picture = false; 53123730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) 53223730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) bool include_borders = true; 53323730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) for (TilingData::Iterator it(&tiling_, record_rect, include_borders); it; 53423730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) ++it) { 535f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) const PictureMapKey& key = it.index(); 536f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) gfx::Rect tile = PaddedRect(key); 537f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) if (record_rect.Contains(tile)) { 538f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) PictureInfo& info = picture_map_[key]; 539a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) info.SetPicture(picture); 54023730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) found_tile_for_recorded_picture = true; 541f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) } 5421e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) } 5431320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci DetermineIfSolidColor(); 54423730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) DCHECK(found_tile_for_recorded_picture); 5452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 5462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 54723730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) has_any_recordings_ = true; 54823730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) DCHECK(CanRasterSlowTileCheck(recorded_viewport_)); 5491e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) return true; 5502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 5512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 552116680a4aac90f2aa7413d9095a592090648e557Ben Murdochvoid PicturePile::SetEmptyBounds() { 553116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch tiling_.SetTilingSize(gfx::Size()); 554116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch picture_map_.clear(); 555116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch has_any_recordings_ = false; 556116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch recorded_viewport_ = gfx::Rect(); 557116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch} 558116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 5591320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tuccivoid PicturePile::DetermineIfSolidColor() { 5601320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci is_solid_color_ = false; 5611320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci solid_color_ = SK_ColorTRANSPARENT; 5621320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 5631320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci if (picture_map_.empty()) { 5641320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci return; 5651320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci } 5661320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 5671320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci PictureMap::const_iterator it = picture_map_.begin(); 5681320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci const Picture* picture = it->second.GetPicture(); 5691320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 5701320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci // Missing recordings due to frequent invalidations or being too far away 5711320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci // from the interest rect will cause the a null picture to exist. 5721320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci if (!picture) 5731320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci return; 5741320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 5751320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci // Don't bother doing more work if the first image is too complicated. 5761320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci if (picture->ApproximateOpCount() > kOpCountThatIsOkToAnalyze) 5771320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci return; 5781320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 5791320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci // Make sure all of the mapped images point to the same picture. 5801320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci for (++it; it != picture_map_.end(); ++it) { 5811320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci if (it->second.GetPicture() != picture) 5821320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci return; 5831320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci } 5841320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci skia::AnalysisCanvas canvas(recorded_viewport_.width(), 5851320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci recorded_viewport_.height()); 5865b892326406927b709cdaf6c384d4ababf456332Ben Murdoch canvas.translate(-recorded_viewport_.x(), -recorded_viewport_.y()); 5875b892326406927b709cdaf6c384d4ababf456332Ben Murdoch picture->Raster(&canvas, nullptr, Region(), 1.0f); 5881320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci is_solid_color_ = canvas.GetColorIfSolid(&solid_color_); 5891320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci} 5901320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 5912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} // namespace cc 592