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

Side by Side Diff: cc/resources/picture_pile.cc

Issue 723343002: Update from https://crrev.com/304121 (Closed) Base URL: git@github.com:domokit/mojo.git@master
Patch Set: Created 6 years, 1 month 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/resources/picture_pile.h ('k') | cc/resources/picture_pile_base.h » ('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/resources/picture_pile.h" 5 #include "cc/resources/picture_pile.h"
6 6
7 #include <algorithm> 7 #include <algorithm>
8 #include <limits> 8 #include <limits>
9 #include <vector> 9 #include <vector>
10 10
11 #include "cc/base/region.h" 11 #include "cc/base/region.h"
12 #include "cc/debug/rendering_stats_instrumentation.h" 12 #include "cc/resources/picture_pile_impl.h"
13 #include "cc/resources/raster_worker_pool.h" 13 #include "cc/resources/raster_worker_pool.h"
14 #include "skia/ext/analysis_canvas.h" 14 #include "skia/ext/analysis_canvas.h"
15 15
16 namespace { 16 namespace {
17 // Layout pixel buffer around the visible layer rect to record. Any base 17 // Layout pixel buffer around the visible layer rect to record. Any base
18 // picture that intersects the visible layer rect expanded by this distance 18 // picture that intersects the visible layer rect expanded by this distance
19 // will be recorded. 19 // will be recorded.
20 const int kPixelDistanceToRecord = 8000; 20 const int kPixelDistanceToRecord = 8000;
21 // We don't perform solid color analysis on images that have more than 10 skia 21 // We don't perform solid color analysis on images that have more than 10 skia
22 // operations. 22 // operations.
23 const int kOpCountThatIsOkToAnalyze = 10; 23 const int kOpCountThatIsOkToAnalyze = 10;
24 24
25 // Dimensions of the tiles in this picture pile as well as the dimensions of
26 // the base picture in each tile.
27 const int kBasePictureSize = 512;
28 const int kTileGridBorderPixels = 1;
29 #ifdef NDEBUG
30 const bool kDefaultClearCanvasSetting = false;
31 #else
32 const bool kDefaultClearCanvasSetting = true;
33 #endif
34
35 // Invalidation frequency settings. kInvalidationFrequencyThreshold is a value
36 // between 0 and 1 meaning invalidation frequency between 0% and 100% that
37 // indicates when to stop invalidating offscreen regions.
38 // kFrequentInvalidationDistanceThreshold defines what it means to be
39 // "offscreen" in terms of distance to visible in css pixels.
40 const float kInvalidationFrequencyThreshold = 0.75f;
41 const int kFrequentInvalidationDistanceThreshold = 512;
42
25 // TODO(humper): The density threshold here is somewhat arbitrary; need a 43 // TODO(humper): The density threshold here is somewhat arbitrary; need a
26 // way to set // this from the command line so we can write a benchmark 44 // way to set // this from the command line so we can write a benchmark
27 // script and find a sweet spot. 45 // script and find a sweet spot.
28 const float kDensityThreshold = 0.5f; 46 const float kDensityThreshold = 0.5f;
29 47
30 bool rect_sort_y(const gfx::Rect& r1, const gfx::Rect& r2) { 48 bool rect_sort_y(const gfx::Rect& r1, const gfx::Rect& r2) {
31 return r1.y() < r2.y() || (r1.y() == r2.y() && r1.x() < r2.x()); 49 return r1.y() < r2.y() || (r1.y() == r2.y() && r1.x() < r2.x());
32 } 50 }
33 51
34 bool rect_sort_x(const gfx::Rect& r1, const gfx::Rect& r2) { 52 bool rect_sort_x(const gfx::Rect& r1, const gfx::Rect& r2) {
(...skipping 107 matching lines...) Expand 10 before | Expand all | Expand 10 after
142 160
143 *record_rects = vertical_clustering; 161 *record_rects = vertical_clustering;
144 return vertical_density; 162 return vertical_density;
145 } 163 }
146 164
147 } // namespace 165 } // namespace
148 166
149 namespace cc { 167 namespace cc {
150 168
151 PicturePile::PicturePile() 169 PicturePile::PicturePile()
152 : is_suitable_for_gpu_rasterization_(true), 170 : min_contents_scale_(0),
153 pixel_record_distance_(kPixelDistanceToRecord) { 171 slow_down_raster_scale_factor_for_debug_(0),
172 contents_opaque_(false),
173 contents_fill_bounds_completely_(false),
174 clear_canvas_with_debug_color_(kDefaultClearCanvasSetting),
175 has_any_recordings_(false),
176 is_mask_(false),
177 is_solid_color_(false),
178 solid_color_(SK_ColorTRANSPARENT),
179 pixel_record_distance_(kPixelDistanceToRecord),
180 is_suitable_for_gpu_rasterization_(true) {
181 tiling_.SetMaxTextureSize(gfx::Size(kBasePictureSize, kBasePictureSize));
182 tile_grid_info_.fTileInterval.setEmpty();
183 tile_grid_info_.fMargin.setEmpty();
184 tile_grid_info_.fOffset.setZero();
154 } 185 }
155 186
156 PicturePile::~PicturePile() { 187 PicturePile::~PicturePile() {
157 } 188 }
158 189
159 bool PicturePile::UpdateAndExpandInvalidation( 190 bool PicturePile::UpdateAndExpandInvalidation(
160 ContentLayerClient* painter, 191 ContentLayerClient* painter,
161 Region* invalidation, 192 Region* invalidation,
162 SkColor background_color, 193 SkColor background_color,
163 bool contents_opaque, 194 bool contents_opaque,
164 bool contents_fill_bounds_completely, 195 bool contents_fill_bounds_completely,
165 const gfx::Size& layer_size, 196 const gfx::Size& layer_size,
166 const gfx::Rect& visible_layer_rect, 197 const gfx::Rect& visible_layer_rect,
167 int frame_number, 198 int frame_number,
168 Picture::RecordingMode recording_mode, 199 Picture::RecordingMode recording_mode) {
169 RenderingStatsInstrumentation* stats_instrumentation) {
170 background_color_ = background_color; 200 background_color_ = background_color;
171 contents_opaque_ = contents_opaque; 201 contents_opaque_ = contents_opaque;
172 contents_fill_bounds_completely_ = contents_fill_bounds_completely; 202 contents_fill_bounds_completely_ = contents_fill_bounds_completely;
173 203
174 bool updated = false; 204 bool updated = false;
175 205
176 Region resize_invalidation; 206 Region resize_invalidation;
177 gfx::Size old_tiling_size = tiling_size(); 207 gfx::Size old_tiling_size = GetSize();
178 if (old_tiling_size != layer_size) { 208 if (old_tiling_size != layer_size) {
179 tiling_.SetTilingSize(layer_size); 209 tiling_.SetTilingSize(layer_size);
180 updated = true; 210 updated = true;
181 } 211 }
182 212
183 gfx::Rect interest_rect = visible_layer_rect; 213 gfx::Rect interest_rect = visible_layer_rect;
184 interest_rect.Inset(-pixel_record_distance_, -pixel_record_distance_); 214 interest_rect.Inset(-pixel_record_distance_, -pixel_record_distance_);
185 recorded_viewport_ = interest_rect; 215 recorded_viewport_ = interest_rect;
186 recorded_viewport_.Intersect(gfx::Rect(tiling_size())); 216 recorded_viewport_.Intersect(gfx::Rect(GetSize()));
187 217
188 gfx::Rect interest_rect_over_tiles = 218 gfx::Rect interest_rect_over_tiles =
189 tiling_.ExpandRectToTileBounds(interest_rect); 219 tiling_.ExpandRectToTileBounds(interest_rect);
190 220
221 gfx::Size min_tiling_size(
222 std::min(GetSize().width(), old_tiling_size.width()),
223 std::min(GetSize().height(), old_tiling_size.height()));
224 gfx::Size max_tiling_size(
225 std::max(GetSize().width(), old_tiling_size.width()),
226 std::max(GetSize().height(), old_tiling_size.height()));
227
191 if (old_tiling_size != layer_size) { 228 if (old_tiling_size != layer_size) {
192 has_any_recordings_ = false; 229 has_any_recordings_ = false;
193 230
194 // Drop recordings that are outside the new layer bounds or that changed 231 // Drop recordings that are outside the new or old layer bounds or that
195 // size. 232 // changed size. Newly exposed areas are considered invalidated.
233 // Previously exposed areas that are now outside of bounds also need to
234 // be invalidated, as they may become part of raster when scale < 1.
196 std::vector<PictureMapKey> to_erase; 235 std::vector<PictureMapKey> to_erase;
197 int min_toss_x = tiling_.num_tiles_x(); 236 int min_toss_x = tiling_.num_tiles_x();
198 if (tiling_size().width() > old_tiling_size.width()) { 237 if (max_tiling_size.width() > min_tiling_size.width()) {
199 min_toss_x = 238 min_toss_x =
200 tiling_.FirstBorderTileXIndexFromSrcCoord(old_tiling_size.width()); 239 tiling_.FirstBorderTileXIndexFromSrcCoord(min_tiling_size.width());
201 } 240 }
202 int min_toss_y = tiling_.num_tiles_y(); 241 int min_toss_y = tiling_.num_tiles_y();
203 if (tiling_size().height() > old_tiling_size.height()) { 242 if (max_tiling_size.height() > min_tiling_size.height()) {
204 min_toss_y = 243 min_toss_y =
205 tiling_.FirstBorderTileYIndexFromSrcCoord(old_tiling_size.height()); 244 tiling_.FirstBorderTileYIndexFromSrcCoord(min_tiling_size.height());
206 } 245 }
207 for (PictureMap::const_iterator it = picture_map_.begin(); 246 for (PictureMap::const_iterator it = picture_map_.begin();
208 it != picture_map_.end(); 247 it != picture_map_.end();
209 ++it) { 248 ++it) {
210 const PictureMapKey& key = it->first; 249 const PictureMapKey& key = it->first;
211 if (key.first < min_toss_x && key.second < min_toss_y) { 250 if (key.first < min_toss_x && key.second < min_toss_y) {
212 has_any_recordings_ |= !!it->second.GetPicture(); 251 has_any_recordings_ |= !!it->second.GetPicture();
213 continue; 252 continue;
214 } 253 }
215 to_erase.push_back(key); 254 to_erase.push_back(key);
216 } 255 }
217 256
218 for (size_t i = 0; i < to_erase.size(); ++i) 257 for (size_t i = 0; i < to_erase.size(); ++i)
219 picture_map_.erase(to_erase[i]); 258 picture_map_.erase(to_erase[i]);
220 259
221 // If a recording is dropped and not re-recorded below, invalidate that 260 // If a recording is dropped and not re-recorded below, invalidate that
222 // full recording to cause any raster tiles that would use it to be 261 // full recording to cause any raster tiles that would use it to be
223 // dropped. 262 // dropped.
224 // If the recording will be replaced below, just invalidate newly exposed 263 // If the recording will be replaced below, invalidate newly exposed
225 // areas to force raster tiles that include the old recording to know 264 // areas and previously exposed areas to force raster tiles that include the
226 // there is new recording to display. 265 // old recording to know there is new recording to display.
227 gfx::Rect old_tiling_rect_over_tiles = 266 gfx::Rect min_tiling_rect_over_tiles =
228 tiling_.ExpandRectToTileBounds(gfx::Rect(old_tiling_size)); 267 tiling_.ExpandRectToTileBounds(gfx::Rect(min_tiling_size));
229 if (min_toss_x < tiling_.num_tiles_x()) { 268 if (min_toss_x < tiling_.num_tiles_x()) {
230 // The bounds which we want to invalidate are the tiles along the old 269 // The bounds which we want to invalidate are the tiles along the old
231 // edge of the pile. We'll call this bounding box the OLD EDGE RECT. 270 // edge of the pile when expanding, or the new edge of the pile when
271 // shrinking. In either case, it's the difference of the two, so we'll
272 // call this bounding box the DELTA EDGE RECT.
232 // 273 //
233 // In the picture below, the old edge rect would be the bounding box 274 // In the picture below, the delta edge rect would be the bounding box of
234 // of tiles {h,i,j}. |min_toss_x| would be equal to the horizontal index 275 // tiles {h,i,j}. |min_toss_x| would be equal to the horizontal index of
235 // of the same tiles. 276 // the same tiles.
236 // 277 //
237 // old pile edge-v new pile edge-v 278 // min pile edge-v max pile edge-v
238 // ---------------+ - - - - - - - -+ 279 // ---------------+ - - - - - - - -+
239 // mmppssvvyybbeeh|h . 280 // mmppssvvyybbeeh|h .
240 // mmppssvvyybbeeh|h . 281 // mmppssvvyybbeeh|h .
241 // nnqqttwwzzccffi|i . 282 // nnqqttwwzzccffi|i .
242 // nnqqttwwzzccffi|i . 283 // nnqqttwwzzccffi|i .
243 // oorruuxxaaddggj|j . 284 // oorruuxxaaddggj|j .
244 // oorruuxxaaddggj|j . 285 // oorruuxxaaddggj|j .
245 // ---------------+ - - - - - - - -+ <- old pile edge 286 // ---------------+ - - - - - - - -+ <- min pile edge
246 // . 287 // .
247 // - - - - - - - - - - - - - - - -+ <- new pile edge 288 // - - - - - - - - - - - - - - - -+ <- max pile edge
248 // 289 //
249 // If you were to slide a vertical beam from the left edge of the 290 // If you were to slide a vertical beam from the left edge of the
250 // old edge rect toward the right, it would either hit the right edge 291 // delta edge rect toward the right, it would either hit the right edge
251 // of the old edge rect, or the interest rect (expanded to the bounds 292 // of the delta edge rect, or the interest rect (expanded to the bounds
252 // of the tiles it touches). The same is true for a beam parallel to 293 // of the tiles it touches). The same is true for a beam parallel to
253 // any of the four edges, sliding accross the old edge rect. We use 294 // any of the four edges, sliding across the delta edge rect. We use
254 // the union of these four rectangles generated by these beams to 295 // the union of these four rectangles generated by these beams to
255 // determine which part of the old edge rect is outside of the expanded 296 // determine which part of the delta edge rect is outside of the expanded
256 // interest rect. 297 // interest rect.
257 // 298 //
258 // Case 1: Intersect rect is outside the old edge rect. It can be 299 // Case 1: Intersect rect is outside the delta edge rect. It can be
259 // either on the left or the right. The |left_rect| and |right_rect|, 300 // either on the left or the right. The |left_rect| and |right_rect|,
260 // cover this case, one will be empty and one will cover the full 301 // cover this case, one will be empty and one will cover the full
261 // old edge rect. In the picture below, |left_rect| would cover the 302 // delta edge rect. In the picture below, |left_rect| would cover the
262 // old edge rect, and |right_rect| would be empty. 303 // delta edge rect, and |right_rect| would be empty.
263 // +----------------------+ |^^^^^^^^^^^^^^^| 304 // +----------------------+ |^^^^^^^^^^^^^^^|
264 // |===> OLD EDGE RECT | | | 305 // |===> DELTA EDGE RECT | | |
265 // |===> | | INTEREST RECT | 306 // |===> | | INTEREST RECT |
266 // |===> | | | 307 // |===> | | |
267 // |===> | | | 308 // |===> | | |
268 // +----------------------+ |vvvvvvvvvvvvvvv| 309 // +----------------------+ |vvvvvvvvvvvvvvv|
269 // 310 //
270 // Case 2: Interest rect is inside the old edge rect. It will always 311 // Case 2: Interest rect is inside the delta edge rect. It will always
271 // fill the entire old edge rect horizontally since the old edge rect 312 // fill the entire delta edge rect horizontally since the old edge rect
272 // is a single tile wide, and the interest rect has been expanded to the 313 // is a single tile wide, and the interest rect has been expanded to the
273 // bounds of the tiles it touches. In this case the |left_rect| and 314 // bounds of the tiles it touches. In this case the |left_rect| and
274 // |right_rect| will be empty, but the case is handled by the |top_rect| 315 // |right_rect| will be empty, but the case is handled by the |top_rect|
275 // and |bottom_rect|. In the picture below, neither the |top_rect| nor 316 // and |bottom_rect|. In the picture below, neither the |top_rect| nor
276 // |bottom_rect| would empty, they would each cover the area of the old 317 // |bottom_rect| would empty, they would each cover the area of the old
277 // edge rect outside the expanded interest rect. 318 // edge rect outside the expanded interest rect.
278 // +-----------------+ 319 // +-----------------+
279 // |:::::::::::::::::| 320 // |:::::::::::::::::|
280 // |:::::::::::::::::| 321 // |:::::::::::::::::|
281 // |vvvvvvvvvvvvvvvvv| 322 // |vvvvvvvvvvvvvvvvv|
282 // | | 323 // | |
283 // +-----------------+ 324 // +-----------------+
284 // | INTEREST RECT | 325 // | INTEREST RECT |
285 // | | 326 // | |
286 // +-----------------+ 327 // +-----------------+
287 // | | 328 // | |
288 // | OLD EDGE RECT | 329 // | DELTA EDGE RECT |
289 // +-----------------+ 330 // +-----------------+
290 // 331 //
291 // Lastly, we need to consider tiles inside the expanded interest rect. 332 // Lastly, we need to consider tiles inside the expanded interest rect.
292 // For those tiles, we want to invalidate exactly the newly exposed 333 // For those tiles, we want to invalidate exactly the newly exposed
293 // pixels. In the picture below the tiles in the old edge rect have been 334 // pixels. In the picture below the tiles in the delta edge rect have
294 // resized and the area covered by periods must be invalidated. The 335 // been resized and the area covered by periods must be invalidated. The
295 // |exposed_rect| will cover exactly that area. 336 // |exposed_rect| will cover exactly that area.
296 // v-old pile edge 337 // v-min pile edge
297 // +---------+-------+ 338 // +---------+-------+
298 // | ........| 339 // | ........|
299 // | ........| 340 // | ........|
300 // | OLD EDGE.RECT..| 341 // | DELTA EDGE.RECT.|
301 // | ........| 342 // | ........|
302 // | ........| 343 // | ........|
303 // | ........| 344 // | ........|
304 // | ........| 345 // | ........|
305 // | ........| 346 // | ........|
306 // | ........| 347 // | ........|
307 // +---------+-------+ 348 // +---------+-------+
308 349
309 int left = tiling_.TilePositionX(min_toss_x); 350 int left = tiling_.TilePositionX(min_toss_x);
310 int right = left + tiling_.TileSizeX(min_toss_x); 351 int right = left + tiling_.TileSizeX(min_toss_x);
311 int top = old_tiling_rect_over_tiles.y(); 352 int top = min_tiling_rect_over_tiles.y();
312 int bottom = old_tiling_rect_over_tiles.bottom(); 353 int bottom = min_tiling_rect_over_tiles.bottom();
313 354
314 int left_until = std::min(interest_rect_over_tiles.x(), right); 355 int left_until = std::min(interest_rect_over_tiles.x(), right);
315 int right_until = std::max(interest_rect_over_tiles.right(), left); 356 int right_until = std::max(interest_rect_over_tiles.right(), left);
316 int top_until = std::min(interest_rect_over_tiles.y(), bottom); 357 int top_until = std::min(interest_rect_over_tiles.y(), bottom);
317 int bottom_until = std::max(interest_rect_over_tiles.bottom(), top); 358 int bottom_until = std::max(interest_rect_over_tiles.bottom(), top);
318 359
319 int exposed_left = old_tiling_size.width(); 360 int exposed_left = min_tiling_size.width();
320 int exposed_left_until = tiling_size().width(); 361 int exposed_left_until = max_tiling_size.width();
321 int exposed_top = top; 362 int exposed_top = top;
322 int exposed_bottom = tiling_size().height(); 363 int exposed_bottom = max_tiling_size.height();
323 DCHECK_GE(exposed_left, left); 364 DCHECK_GE(exposed_left, left);
324 365
325 gfx::Rect left_rect(left, top, left_until - left, bottom - top); 366 gfx::Rect left_rect(left, top, left_until - left, bottom - top);
326 gfx::Rect right_rect(right_until, top, right - right_until, bottom - top); 367 gfx::Rect right_rect(right_until, top, right - right_until, bottom - top);
327 gfx::Rect top_rect(left, top, right - left, top_until - top); 368 gfx::Rect top_rect(left, top, right - left, top_until - top);
328 gfx::Rect bottom_rect( 369 gfx::Rect bottom_rect(
329 left, bottom_until, right - left, bottom - bottom_until); 370 left, bottom_until, right - left, bottom - bottom_until);
330 gfx::Rect exposed_rect(exposed_left, 371 gfx::Rect exposed_rect(exposed_left,
331 exposed_top, 372 exposed_top,
332 exposed_left_until - exposed_left, 373 exposed_left_until - exposed_left,
333 exposed_bottom - exposed_top); 374 exposed_bottom - exposed_top);
334 resize_invalidation.Union(left_rect); 375 resize_invalidation.Union(left_rect);
335 resize_invalidation.Union(right_rect); 376 resize_invalidation.Union(right_rect);
336 resize_invalidation.Union(top_rect); 377 resize_invalidation.Union(top_rect);
337 resize_invalidation.Union(bottom_rect); 378 resize_invalidation.Union(bottom_rect);
338 resize_invalidation.Union(exposed_rect); 379 resize_invalidation.Union(exposed_rect);
339 } 380 }
340 if (min_toss_y < tiling_.num_tiles_y()) { 381 if (min_toss_y < tiling_.num_tiles_y()) {
341 // The same thing occurs here as in the case above, but the invalidation 382 // The same thing occurs here as in the case above, but the invalidation
342 // rect is the bounding box around the bottom row of tiles in the old 383 // rect is the bounding box around the bottom row of tiles in the min
343 // pile. This would be tiles {o,r,u,x,a,d,g,j} in the above picture. 384 // pile. This would be tiles {o,r,u,x,a,d,g,j} in the above picture.
344 385
345 int top = tiling_.TilePositionY(min_toss_y); 386 int top = tiling_.TilePositionY(min_toss_y);
346 int bottom = top + tiling_.TileSizeY(min_toss_y); 387 int bottom = top + tiling_.TileSizeY(min_toss_y);
347 int left = old_tiling_rect_over_tiles.x(); 388 int left = min_tiling_rect_over_tiles.x();
348 int right = old_tiling_rect_over_tiles.right(); 389 int right = min_tiling_rect_over_tiles.right();
349 390
350 int top_until = std::min(interest_rect_over_tiles.y(), bottom); 391 int top_until = std::min(interest_rect_over_tiles.y(), bottom);
351 int bottom_until = std::max(interest_rect_over_tiles.bottom(), top); 392 int bottom_until = std::max(interest_rect_over_tiles.bottom(), top);
352 int left_until = std::min(interest_rect_over_tiles.x(), right); 393 int left_until = std::min(interest_rect_over_tiles.x(), right);
353 int right_until = std::max(interest_rect_over_tiles.right(), left); 394 int right_until = std::max(interest_rect_over_tiles.right(), left);
354 395
355 int exposed_top = old_tiling_size.height(); 396 int exposed_top = min_tiling_size.height();
356 int exposed_top_until = tiling_size().height(); 397 int exposed_top_until = max_tiling_size.height();
357 int exposed_left = left; 398 int exposed_left = left;
358 int exposed_right = tiling_size().width(); 399 int exposed_right = max_tiling_size.width();
359 DCHECK_GE(exposed_top, top); 400 DCHECK_GE(exposed_top, top);
360 401
361 gfx::Rect left_rect(left, top, left_until - left, bottom - top); 402 gfx::Rect left_rect(left, top, left_until - left, bottom - top);
362 gfx::Rect right_rect(right_until, top, right - right_until, bottom - top); 403 gfx::Rect right_rect(right_until, top, right - right_until, bottom - top);
363 gfx::Rect top_rect(left, top, right - left, top_until - top); 404 gfx::Rect top_rect(left, top, right - left, top_until - top);
364 gfx::Rect bottom_rect( 405 gfx::Rect bottom_rect(
365 left, bottom_until, right - left, bottom - bottom_until); 406 left, bottom_until, right - left, bottom - bottom_until);
366 gfx::Rect exposed_rect(exposed_left, 407 gfx::Rect exposed_rect(exposed_left,
367 exposed_top, 408 exposed_top,
368 exposed_right - exposed_left, 409 exposed_right - exposed_left,
369 exposed_top_until - exposed_top); 410 exposed_top_until - exposed_top);
370 resize_invalidation.Union(left_rect); 411 resize_invalidation.Union(left_rect);
371 resize_invalidation.Union(right_rect); 412 resize_invalidation.Union(right_rect);
372 resize_invalidation.Union(top_rect); 413 resize_invalidation.Union(top_rect);
373 resize_invalidation.Union(bottom_rect); 414 resize_invalidation.Union(bottom_rect);
374 resize_invalidation.Union(exposed_rect); 415 resize_invalidation.Union(exposed_rect);
375 } 416 }
376 } 417 }
377 418
378 // Detect cases where the full pile is invalidated, in this situation we 419 // Detect cases where the full pile is invalidated, in this situation we
379 // can just drop/invalidate everything. 420 // can just drop/invalidate everything.
380 if (invalidation->Contains(gfx::Rect(old_tiling_size)) || 421 if (invalidation->Contains(gfx::Rect(old_tiling_size)) ||
381 invalidation->Contains(gfx::Rect(tiling_size()))) { 422 invalidation->Contains(gfx::Rect(GetSize()))) {
382 for (auto& it : picture_map_) 423 for (auto& it : picture_map_)
383 updated = it.second.Invalidate(frame_number) || updated; 424 updated = it.second.Invalidate(frame_number) || updated;
384 } else { 425 } else {
385 // Expand invalidation that is on tiles that aren't in the interest rect and 426 // Expand invalidation that is on tiles that aren't in the interest rect and
386 // will not be re-recorded below. These tiles are no longer valid and should 427 // will not be re-recorded below. These tiles are no longer valid and should
387 // be considerered fully invalid, so we can know to not keep around raster 428 // be considerered fully invalid, so we can know to not keep around raster
388 // tiles that intersect with these recording tiles. 429 // tiles that intersect with these recording tiles.
389 Region invalidation_expanded_to_full_tiles; 430 Region invalidation_expanded_to_full_tiles;
390 431
391 for (Region::Iterator i(*invalidation); i.has_rect(); i.next()) { 432 for (Region::Iterator i(*invalidation); i.has_rect(); i.next()) {
(...skipping 90 matching lines...) Expand 10 before | Expand all | Expand 10 after
482 int repeat_count = std::max(1, slow_down_raster_scale_factor_for_debug_); 523 int repeat_count = std::max(1, slow_down_raster_scale_factor_for_debug_);
483 scoped_refptr<Picture> picture; 524 scoped_refptr<Picture> picture;
484 525
485 // Note: Currently, gathering of pixel refs when using a single 526 // Note: Currently, gathering of pixel refs when using a single
486 // raster thread doesn't provide any benefit. This might change 527 // raster thread doesn't provide any benefit. This might change
487 // in the future but we avoid it for now to reduce the cost of 528 // in the future but we avoid it for now to reduce the cost of
488 // Picture::Create. 529 // Picture::Create.
489 bool gather_pixel_refs = RasterWorkerPool::GetNumRasterThreads() > 1; 530 bool gather_pixel_refs = RasterWorkerPool::GetNumRasterThreads() > 1;
490 531
491 { 532 {
492 base::TimeDelta best_duration = base::TimeDelta::Max();
493 for (int i = 0; i < repeat_count; i++) { 533 for (int i = 0; i < repeat_count; i++) {
494 base::TimeTicks start_time = stats_instrumentation->StartRecording();
495 picture = Picture::Create(record_rect, 534 picture = Picture::Create(record_rect,
496 painter, 535 painter,
497 tile_grid_info_, 536 tile_grid_info_,
498 gather_pixel_refs, 537 gather_pixel_refs,
499 recording_mode); 538 recording_mode);
500 // Note the '&&' with previous is-suitable state. 539 // Note the '&&' with previous is-suitable state.
501 // This means that once a picture-pile becomes unsuitable for gpu 540 // This means that once a picture-pile becomes unsuitable for gpu
502 // rasterization due to some content, it will continue to be unsuitable 541 // rasterization due to some content, it will continue to be unsuitable
503 // even if that content is replaced by gpu-friendly content. 542 // even if that content is replaced by gpu-friendly content.
504 // This is an optimization to avoid iterating though all pictures in 543 // This is an optimization to avoid iterating though all pictures in
505 // the pile after each invalidation. 544 // the pile after each invalidation.
506 is_suitable_for_gpu_rasterization_ &= 545 is_suitable_for_gpu_rasterization_ &=
507 picture->IsSuitableForGpuRasterization(); 546 picture->IsSuitableForGpuRasterization();
508 base::TimeDelta duration =
509 stats_instrumentation->EndRecording(start_time);
510 best_duration = std::min(duration, best_duration);
511 } 547 }
512 int recorded_pixel_count =
513 picture->LayerRect().width() * picture->LayerRect().height();
514 stats_instrumentation->AddRecord(best_duration, recorded_pixel_count);
515 } 548 }
516 549
517 bool found_tile_for_recorded_picture = false; 550 bool found_tile_for_recorded_picture = false;
518 551
519 bool include_borders = true; 552 bool include_borders = true;
520 for (TilingData::Iterator it(&tiling_, record_rect, include_borders); it; 553 for (TilingData::Iterator it(&tiling_, record_rect, include_borders); it;
521 ++it) { 554 ++it) {
522 const PictureMapKey& key = it.index(); 555 const PictureMapKey& key = it.index();
523 gfx::Rect tile = PaddedRect(key); 556 gfx::Rect tile = PaddedRect(key);
524 if (record_rect.Contains(tile)) { 557 if (record_rect.Contains(tile)) {
525 PictureInfo& info = picture_map_[key]; 558 PictureInfo& info = picture_map_[key];
526 info.SetPicture(picture); 559 info.SetPicture(picture);
527 found_tile_for_recorded_picture = true; 560 found_tile_for_recorded_picture = true;
528 } 561 }
529 } 562 }
530 DetermineIfSolidColor(); 563 DetermineIfSolidColor();
531 DCHECK(found_tile_for_recorded_picture); 564 DCHECK(found_tile_for_recorded_picture);
532 } 565 }
533 566
534 has_any_recordings_ = true; 567 has_any_recordings_ = true;
535 DCHECK(CanRasterSlowTileCheck(recorded_viewport_)); 568 DCHECK(CanRasterSlowTileCheck(recorded_viewport_));
536 return true; 569 return true;
537 } 570 }
538 571
572 gfx::Size PicturePile::GetSize() const {
573 return tiling_.tiling_size();
574 }
575
539 void PicturePile::SetEmptyBounds() { 576 void PicturePile::SetEmptyBounds() {
540 tiling_.SetTilingSize(gfx::Size()); 577 tiling_.SetTilingSize(gfx::Size());
541 Clear(); 578 Clear();
542 } 579 }
543 580
581 void PicturePile::SetMinContentsScale(float min_contents_scale) {
582 DCHECK(min_contents_scale);
583 if (min_contents_scale_ == min_contents_scale)
584 return;
585
586 // Picture contents are played back scaled. When the final contents scale is
587 // less than 1 (i.e. low res), then multiple recorded pixels will be used
588 // to raster one final pixel. To avoid splitting a final pixel across
589 // pictures (which would result in incorrect rasterization due to blending), a
590 // buffer margin is added so that any picture can be snapped to integral
591 // final pixels.
592 //
593 // For example, if a 1/4 contents scale is used, then that would be 3 buffer
594 // pixels, since that's the minimum number of pixels to add so that resulting
595 // content can be snapped to a four pixel aligned grid.
596 int buffer_pixels = static_cast<int>(ceil(1 / min_contents_scale) - 1);
597 buffer_pixels = std::max(0, buffer_pixels);
598 SetBufferPixels(buffer_pixels);
599 min_contents_scale_ = min_contents_scale;
600 }
601
602 // static
603 void PicturePile::ComputeTileGridInfo(const gfx::Size& tile_grid_size,
604 SkTileGridFactory::TileGridInfo* info) {
605 DCHECK(info);
606 info->fTileInterval.set(tile_grid_size.width() - 2 * kTileGridBorderPixels,
607 tile_grid_size.height() - 2 * kTileGridBorderPixels);
608 DCHECK_GT(info->fTileInterval.width(), 0);
609 DCHECK_GT(info->fTileInterval.height(), 0);
610 info->fMargin.set(kTileGridBorderPixels, kTileGridBorderPixels);
611 // Offset the tile grid coordinate space to take into account the fact
612 // that the top-most and left-most tiles do not have top and left borders
613 // respectively.
614 info->fOffset.set(-kTileGridBorderPixels, -kTileGridBorderPixels);
615 }
616
617 void PicturePile::SetTileGridSize(const gfx::Size& tile_grid_size) {
618 ComputeTileGridInfo(tile_grid_size, &tile_grid_info_);
619 }
620
621 void PicturePile::SetSlowdownRasterScaleFactor(int factor) {
622 slow_down_raster_scale_factor_for_debug_ = factor;
623 }
624
625 void PicturePile::SetIsMask(bool is_mask) {
626 is_mask_ = is_mask;
627 }
628
629 void PicturePile::SetUnsuitableForGpuRasterizationForTesting() {
630 is_suitable_for_gpu_rasterization_ = false;
631 }
632
633 bool PicturePile::IsSuitableForGpuRasterization() const {
634 return is_suitable_for_gpu_rasterization_;
635 }
636
637 scoped_refptr<RasterSource> PicturePile::CreateRasterSource() const {
638 return scoped_refptr<RasterSource>(
639 PicturePileImpl::CreateFromPicturePile(this));
640 }
641
642 SkTileGridFactory::TileGridInfo PicturePile::GetTileGridInfoForTesting() const {
643 return tile_grid_info_;
644 }
645
646 bool PicturePile::CanRasterSlowTileCheck(const gfx::Rect& layer_rect) const {
647 bool include_borders = false;
648 for (TilingData::Iterator tile_iter(&tiling_, layer_rect, include_borders);
649 tile_iter; ++tile_iter) {
650 PictureMap::const_iterator map_iter = picture_map_.find(tile_iter.index());
651 if (map_iter == picture_map_.end())
652 return false;
653 if (!map_iter->second.GetPicture())
654 return false;
655 }
656 return true;
657 }
658
544 void PicturePile::DetermineIfSolidColor() { 659 void PicturePile::DetermineIfSolidColor() {
545 is_solid_color_ = false; 660 is_solid_color_ = false;
546 solid_color_ = SK_ColorTRANSPARENT; 661 solid_color_ = SK_ColorTRANSPARENT;
547 662
548 if (picture_map_.empty()) { 663 if (picture_map_.empty()) {
549 return; 664 return;
550 } 665 }
551 666
552 PictureMap::const_iterator it = picture_map_.begin(); 667 PictureMap::const_iterator it = picture_map_.begin();
553 const Picture* picture = it->second.GetPicture(); 668 const Picture* picture = it->second.GetPicture();
(...skipping 12 matching lines...) Expand all
566 if (it->second.GetPicture() != picture) 681 if (it->second.GetPicture() != picture)
567 return; 682 return;
568 } 683 }
569 skia::AnalysisCanvas canvas(recorded_viewport_.width(), 684 skia::AnalysisCanvas canvas(recorded_viewport_.width(),
570 recorded_viewport_.height()); 685 recorded_viewport_.height());
571 canvas.translate(-recorded_viewport_.x(), -recorded_viewport_.y()); 686 canvas.translate(-recorded_viewport_.x(), -recorded_viewport_.y());
572 picture->Raster(&canvas, nullptr, Region(), 1.0f); 687 picture->Raster(&canvas, nullptr, Region(), 1.0f);
573 is_solid_color_ = canvas.GetColorIfSolid(&solid_color_); 688 is_solid_color_ = canvas.GetColorIfSolid(&solid_color_);
574 } 689 }
575 690
691 gfx::Rect PicturePile::PaddedRect(const PictureMapKey& key) const {
692 gfx::Rect tile = tiling_.TileBounds(key.first, key.second);
693 return PadRect(tile);
694 }
695
696 gfx::Rect PicturePile::PadRect(const gfx::Rect& rect) const {
697 gfx::Rect padded_rect = rect;
698 padded_rect.Inset(-buffer_pixels(), -buffer_pixels(), -buffer_pixels(),
699 -buffer_pixels());
700 return padded_rect;
701 }
702
703 void PicturePile::Clear() {
704 picture_map_.clear();
705 recorded_viewport_ = gfx::Rect();
706 has_any_recordings_ = false;
707 is_solid_color_ = false;
708 }
709
710 PicturePile::PictureInfo::PictureInfo() : last_frame_number_(0) {
711 }
712
713 PicturePile::PictureInfo::~PictureInfo() {
714 }
715
716 void PicturePile::PictureInfo::AdvanceInvalidationHistory(int frame_number) {
717 DCHECK_GE(frame_number, last_frame_number_);
718 if (frame_number == last_frame_number_)
719 return;
720
721 invalidation_history_ <<= (frame_number - last_frame_number_);
722 last_frame_number_ = frame_number;
723 }
724
725 bool PicturePile::PictureInfo::Invalidate(int frame_number) {
726 AdvanceInvalidationHistory(frame_number);
727 invalidation_history_.set(0);
728
729 bool did_invalidate = !!picture_.get();
730 picture_ = NULL;
731 return did_invalidate;
732 }
733
734 bool PicturePile::PictureInfo::NeedsRecording(int frame_number,
735 int distance_to_visible) {
736 AdvanceInvalidationHistory(frame_number);
737
738 // We only need recording if we don't have a picture. Furthermore, we only
739 // need a recording if we're within frequent invalidation distance threshold
740 // or the invalidation is not frequent enough (below invalidation frequency
741 // threshold).
742 return !picture_.get() &&
743 ((distance_to_visible <= kFrequentInvalidationDistanceThreshold) ||
744 (GetInvalidationFrequency() < kInvalidationFrequencyThreshold));
745 }
746
747 void PicturePile::SetBufferPixels(int new_buffer_pixels) {
748 if (new_buffer_pixels == buffer_pixels())
749 return;
750
751 Clear();
752 tiling_.SetBorderTexels(new_buffer_pixels);
753 }
754
755 void PicturePile::PictureInfo::SetPicture(scoped_refptr<Picture> picture) {
756 picture_ = picture;
757 }
758
759 const Picture* PicturePile::PictureInfo::GetPicture() const {
760 return picture_.get();
761 }
762
763 float PicturePile::PictureInfo::GetInvalidationFrequency() const {
764 return invalidation_history_.count() /
765 static_cast<float>(INVALIDATION_FRAMES_TRACKED);
766 }
767
576 } // namespace cc 768 } // namespace cc
OLDNEW
« no previous file with comments | « cc/resources/picture_pile.h ('k') | cc/resources/picture_pile_base.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698