OLD | NEW |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 |
OLD | NEW |