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

Side by Side Diff: cc/trees/damage_tracker.cc

Issue 2873593002: Force use of and cache render surface. (Closed)
Patch Set: Reduce unneeded code in surface aggregator and add more test. Created 3 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 // Copyright 2011 The Chromium Authors. All rights reserved. 1 // Copyright 2011 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/trees/damage_tracker.h" 5 #include "cc/trees/damage_tracker.h"
6 6
7 #include <stddef.h> 7 #include <stddef.h>
8 8
9 #include <algorithm> 9 #include <algorithm>
10 10
11 #include "base/memory/ptr_util.h" 11 #include "base/memory/ptr_util.h"
12 #include "cc/base/filter_operations.h" 12 #include "cc/base/filter_operations.h"
13 #include "cc/base/math_util.h" 13 #include "cc/base/math_util.h"
14 #include "cc/layers/heads_up_display_layer_impl.h" 14 #include "cc/layers/heads_up_display_layer_impl.h"
15 #include "cc/layers/layer_impl.h" 15 #include "cc/layers/layer_impl.h"
16 #include "cc/layers/render_surface_impl.h" 16 #include "cc/layers/render_surface_impl.h"
17 #include "cc/trees/effect_node.h" 17 #include "cc/trees/effect_node.h"
18 #include "cc/trees/layer_tree_host_common.h" 18 #include "cc/trees/layer_tree_host_common.h"
19 #include "cc/trees/layer_tree_impl.h" 19 #include "cc/trees/layer_tree_impl.h"
20 #include "ui/gfx/geometry/rect_conversions.h" 20 #include "ui/gfx/geometry/rect_conversions.h"
21 21
22 namespace cc { 22 namespace cc {
23 23
24 std::unique_ptr<DamageTracker> DamageTracker::Create() { 24 std::unique_ptr<DamageTracker> DamageTracker::Create() {
25 return base::WrapUnique(new DamageTracker()); 25 return base::WrapUnique(new DamageTracker());
26 } 26 }
27 27
28 DamageTracker::DamageTracker() 28 DamageTracker::DamageTracker() : mailboxId_(0) {}
29 : mailboxId_(0) {}
30 29
31 DamageTracker::~DamageTracker() {} 30 DamageTracker::~DamageTracker() {}
32 31
33 void DamageTracker::UpdateDamageTracking( 32 void DamageTracker::UpdateDamageTracking(
34 LayerTreeImpl* layer_tree_impl, 33 LayerTreeImpl* layer_tree_impl,
35 const RenderSurfaceList& render_surface_list) { 34 const RenderSurfaceList& render_surface_list) {
36 // 35 //
37 // This function computes the "damage rect" of each target surface, and 36 // This function computes the "damage rect" of each target surface, and
38 // updates the state that is used to correctly track damage across frames. The 37 // updates the state that is used to correctly track damage across frames. The
39 // damage rect is the region of the surface that may have changed and needs to 38 // damage rect is the region of the surface that may have changed and needs to
(...skipping 128 matching lines...) Expand 10 before | Expand all | Expand 10 after
168 // All damage from contributing layers and surfaces must already have been 167 // All damage from contributing layers and surfaces must already have been
169 // added to damage_for_this_update_ through calls to AccumulateDamageFromLayer 168 // added to damage_for_this_update_ through calls to AccumulateDamageFromLayer
170 // and AccumulateDamageFromRenderSurface. 169 // and AccumulateDamageFromRenderSurface.
171 170
172 // These functions cannot be bypassed with early-exits, even if we know what 171 // These functions cannot be bypassed with early-exits, even if we know what
173 // the damage will be for this frame, because we need to update the damage 172 // the damage will be for this frame, because we need to update the damage
174 // tracker state to correctly track the next frame. 173 // tracker state to correctly track the next frame.
175 DamageAccumulator damage_from_surface_mask = 174 DamageAccumulator damage_from_surface_mask =
176 TrackDamageFromSurfaceMask(render_surface->MaskLayer()); 175 TrackDamageFromSurfaceMask(render_surface->MaskLayer());
177 DamageAccumulator damage_from_leftover_rects = TrackDamageFromLeftoverRects(); 176 DamageAccumulator damage_from_leftover_rects = TrackDamageFromLeftoverRects();
177 // True if any layer is removed.
178 has_damage_from_contributing_content_ |=
179 !damage_from_leftover_rects.IsEmpty();
178 180
179 if (render_surface->SurfacePropertyChangedOnlyFromDescendant()) { 181 if (render_surface->SurfacePropertyChangedOnlyFromDescendant()) {
180 damage_for_this_update_ = DamageAccumulator(); 182 damage_for_this_update_ = DamageAccumulator();
181 damage_for_this_update_.Union(render_surface->content_rect()); 183 damage_for_this_update_.Union(render_surface->content_rect());
184 // True if there is surface property change from descendant.
185 has_damage_from_contributing_content_ |= !damage_for_this_update_.IsEmpty();
182 } else { 186 } else {
183 // TODO(shawnsingh): can we clamp this damage to the surface's content rect? 187 // TODO(shawnsingh): can we clamp this damage to the surface's content rect?
184 // (affects performance, but not correctness) 188 // (affects performance, but not correctness)
185 damage_for_this_update_.Union(damage_from_surface_mask); 189 damage_for_this_update_.Union(damage_from_surface_mask);
186 damage_for_this_update_.Union(damage_from_leftover_rects); 190 damage_for_this_update_.Union(damage_from_leftover_rects);
187 191
188 gfx::Rect damage_rect; 192 gfx::Rect damage_rect;
189 bool is_rect_valid = damage_for_this_update_.GetAsRect(&damage_rect); 193 bool is_rect_valid = damage_for_this_update_.GetAsRect(&damage_rect);
190 if (is_rect_valid) { 194 if (is_rect_valid) {
191 damage_rect = render_surface->Filters().MapRect( 195 damage_rect = render_surface->Filters().MapRect(
(...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after
251 !target_surface_mask_layer->update_rect().IsEmpty()) { 255 !target_surface_mask_layer->update_rect().IsEmpty()) {
252 damage.Union(gfx::Rect(target_surface_mask_layer->bounds())); 256 damage.Union(gfx::Rect(target_surface_mask_layer->bounds()));
253 } 257 }
254 258
255 return damage; 259 return damage;
256 } 260 }
257 261
258 void DamageTracker::PrepareForUpdate() { 262 void DamageTracker::PrepareForUpdate() {
259 mailboxId_++; 263 mailboxId_++;
260 damage_for_this_update_ = DamageAccumulator(); 264 damage_for_this_update_ = DamageAccumulator();
265 has_damage_from_contributing_content_ = false;
261 } 266 }
262 267
263 DamageTracker::DamageAccumulator DamageTracker::TrackDamageFromLeftoverRects() { 268 DamageTracker::DamageAccumulator DamageTracker::TrackDamageFromLeftoverRects() {
264 // After computing damage for all active layers, any leftover items in the 269 // After computing damage for all active layers, any leftover items in the
265 // current rect history correspond to layers/surfaces that no longer exist. 270 // current rect history correspond to layers/surfaces that no longer exist.
266 // So, these regions are now exposed on the target surface. 271 // So, these regions are now exposed on the target surface.
267 272
268 DamageAccumulator damage; 273 DamageAccumulator damage;
269 SortedRectMapForLayers::iterator layer_cur_pos = 274 SortedRectMapForLayers::iterator layer_cur_pos =
270 rect_history_for_layers_.begin(); 275 rect_history_for_layers_.begin();
(...skipping 86 matching lines...) Expand 10 before | Expand all | Expand 10 after
357 // 362 //
358 // 2. Repaint/update: If a region of the layer that was repainted/updated, 363 // 2. Repaint/update: If a region of the layer that was repainted/updated,
359 // that region damages the surface. 364 // that region damages the surface.
360 // 365 //
361 // Property changes take priority over update rects. 366 // Property changes take priority over update rects.
362 // 367 //
363 // This method is called when we want to consider how a layer contributes to 368 // This method is called when we want to consider how a layer contributes to
364 // its target RenderSurface, even if that layer owns the target RenderSurface 369 // its target RenderSurface, even if that layer owns the target RenderSurface
365 // itself. To consider how a layer's target surface contributes to the 370 // itself. To consider how a layer's target surface contributes to the
366 // ancestor surface, ExtendDamageForRenderSurface() must be called instead. 371 // ancestor surface, ExtendDamageForRenderSurface() must be called instead.
367
368 bool layer_is_new = false; 372 bool layer_is_new = false;
369 LayerRectMapData& data = RectDataForLayer(layer->id(), &layer_is_new); 373 LayerRectMapData& data = RectDataForLayer(layer->id(), &layer_is_new);
370 gfx::Rect old_rect_in_target_space = data.rect_; 374 gfx::Rect old_rect_in_target_space = data.rect_;
371 375
372 gfx::Rect rect_in_target_space = layer->GetEnclosingRectInTargetSpace(); 376 gfx::Rect rect_in_target_space = layer->GetEnclosingRectInTargetSpace();
373 data.Update(rect_in_target_space, mailboxId_); 377 data.Update(rect_in_target_space, mailboxId_);
374 378
375 if (layer_is_new || layer->LayerPropertyChanged()) { 379 if (layer_is_new || layer->LayerPropertyChanged()) {
376 // If a layer is new or has changed, then its entire layer rect affects the 380 // If a layer is new or has changed, then its entire layer rect affects the
377 // target surface. 381 // target surface.
378 damage_for_this_update_.Union(rect_in_target_space); 382 damage_for_this_update_.Union(rect_in_target_space);
379 383
380 // The layer's old region is now exposed on the target surface, too. 384 // The layer's old region is now exposed on the target surface, too.
381 // Note old_rect_in_target_space is already in target space. 385 // Note old_rect_in_target_space is already in target space.
382 damage_for_this_update_.Union(old_rect_in_target_space); 386 damage_for_this_update_.Union(old_rect_in_target_space);
383 return; 387 } else {
388 // If the layer properties haven't changed, then the the target surface is
389 // only affected by the layer's damaged area, which could be empty.
390 gfx::Rect damage_rect =
391 gfx::UnionRects(layer->update_rect(), layer->damage_rect());
392 damage_rect.Intersect(gfx::Rect(layer->bounds()));
393
394 if (!damage_rect.IsEmpty()) {
395 gfx::Rect damage_rect_in_target_space = MathUtil::MapEnclosingClippedRect(
396 layer->DrawTransform(), damage_rect);
397 damage_for_this_update_.Union(damage_rect_in_target_space);
398 }
384 } 399 }
385 400
386 // If the layer properties haven't changed, then the the target surface is 401 // Property changes from animaiton will not be considered as damage from
387 // only affected by the layer's damaged area, which could be empty. 402 // contributing content.
388 gfx::Rect damage_rect = 403 if (layer_is_new || layer->LayerPropertyChangedNotFromPropertyTrees() ||
389 gfx::UnionRects(layer->update_rect(), layer->damage_rect()); 404 !layer->update_rect().IsEmpty() || !layer->damage_rect().IsEmpty()) {
390 damage_rect.Intersect(gfx::Rect(layer->bounds())); 405 has_damage_from_contributing_content_ |= !damage_for_this_update_.IsEmpty();
391 if (!damage_rect.IsEmpty()) {
392 gfx::Rect damage_rect_in_target_space =
393 MathUtil::MapEnclosingClippedRect(layer->DrawTransform(), damage_rect);
394 damage_for_this_update_.Union(damage_rect_in_target_space);
395 } 406 }
396 } 407 }
397 408
398 void DamageTracker::AccumulateDamageFromRenderSurface( 409 void DamageTracker::AccumulateDamageFromRenderSurface(
399 RenderSurfaceImpl* render_surface) { 410 RenderSurfaceImpl* render_surface) {
400 // There are two ways a "descendant surface" can damage regions of the "target 411 // There are two ways a "descendant surface" can damage regions of the "target
401 // surface": 412 // surface":
402 // 1. Property change: 413 // 1. Property change:
403 // - a surface's geometry can change because of 414 // - a surface's geometry can change because of
404 // - changes to descendants (i.e. the subtree) that affect the 415 // - changes to descendants (i.e. the subtree) that affect the
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after
449 // layer. We expand the damage from this layer too, as we need to readback 460 // layer. We expand the damage from this layer too, as we need to readback
450 // those pixels from the surface with only the contents of layers below this 461 // those pixels from the surface with only the contents of layers below this
451 // one in them. This means we need to redraw any pixels in the surface being 462 // one in them. This means we need to redraw any pixels in the surface being
452 // used for the blur in this layer this frame. 463 // used for the blur in this layer this frame.
453 const FilterOperations& background_filters = 464 const FilterOperations& background_filters =
454 render_surface->BackgroundFilters(); 465 render_surface->BackgroundFilters();
455 if (background_filters.HasFilterThatMovesPixels()) { 466 if (background_filters.HasFilterThatMovesPixels()) {
456 ExpandDamageInsideRectWithFilters(surface_rect_in_target_space, 467 ExpandDamageInsideRectWithFilters(surface_rect_in_target_space,
457 background_filters); 468 background_filters);
458 } 469 }
470
471 // True if any changes from contributing render surface.
472 has_damage_from_contributing_content_ |= !damage_for_this_update_.IsEmpty();
459 } 473 }
460 474
461 bool DamageTracker::DamageAccumulator::GetAsRect(gfx::Rect* rect) { 475 bool DamageTracker::DamageAccumulator::GetAsRect(gfx::Rect* rect) {
462 if (!is_valid_rect_) 476 if (!is_valid_rect_)
463 return false; 477 return false;
464 478
465 base::CheckedNumeric<int> width = right_; 479 base::CheckedNumeric<int> width = right_;
466 width -= x_; 480 width -= x_;
467 base::CheckedNumeric<int> height = bottom_; 481 base::CheckedNumeric<int> height = bottom_;
468 height -= y_; 482 height -= y_;
469 if (!width.IsValid() || !height.IsValid()) { 483 if (!width.IsValid() || !height.IsValid()) {
470 is_valid_rect_ = false; 484 is_valid_rect_ = false;
471 return false; 485 return false;
472 } 486 }
473 487
474 rect->set_x(x_); 488 rect->set_x(x_);
475 rect->set_y(y_); 489 rect->set_y(y_);
476 rect->set_width(width.ValueOrDie()); 490 rect->set_width(width.ValueOrDie());
477 rect->set_height(height.ValueOrDie()); 491 rect->set_height(height.ValueOrDie());
478 return true; 492 return true;
479 } 493 }
480 494
481 } // namespace cc 495 } // namespace cc
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698