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 165 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
357 // | 361 // |
358 // 2. Repaint/update: If a region of the layer that was repainted/updated, | 362 // 2. Repaint/update: If a region of the layer that was repainted/updated, |
359 // that region damages the surface. | 363 // that region damages the surface. |
360 // | 364 // |
361 // Property changes take priority over update rects. | 365 // Property changes take priority over update rects. |
362 // | 366 // |
363 // This method is called when we want to consider how a layer contributes to | 367 // 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 | 368 // its target RenderSurface, even if that layer owns the target RenderSurface |
365 // itself. To consider how a layer's target surface contributes to the | 369 // itself. To consider how a layer's target surface contributes to the |
366 // ancestor surface, ExtendDamageForRenderSurface() must be called instead. | 370 // ancestor surface, ExtendDamageForRenderSurface() must be called instead. |
367 | |
368 bool layer_is_new = false; | 371 bool layer_is_new = false; |
369 LayerRectMapData& data = RectDataForLayer(layer->id(), &layer_is_new); | 372 LayerRectMapData& data = RectDataForLayer(layer->id(), &layer_is_new); |
370 gfx::Rect old_rect_in_target_space = data.rect_; | 373 gfx::Rect old_rect_in_target_space = data.rect_; |
371 | 374 |
372 gfx::Rect rect_in_target_space = layer->GetEnclosingRectInTargetSpace(); | 375 gfx::Rect rect_in_target_space = layer->GetEnclosingRectInTargetSpace(); |
373 data.Update(rect_in_target_space, mailboxId_); | 376 data.Update(rect_in_target_space, mailboxId_); |
374 | 377 |
375 if (layer_is_new || layer->LayerPropertyChanged()) { | 378 if (layer_is_new || layer->LayerPropertyChanged()) { |
376 // If a layer is new or has changed, then its entire layer rect affects the | 379 // If a layer is new or has changed, then its entire layer rect affects the |
377 // target surface. | 380 // target surface. |
378 damage_for_this_update_.Union(rect_in_target_space); | 381 damage_for_this_update_.Union(rect_in_target_space); |
379 | 382 |
380 // The layer's old region is now exposed on the target surface, too. | 383 // 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. | 384 // Note old_rect_in_target_space is already in target space. |
382 damage_for_this_update_.Union(old_rect_in_target_space); | 385 damage_for_this_update_.Union(old_rect_in_target_space); |
383 return; | 386 } else { |
| 387 // If the layer properties haven't changed, then the the target surface is |
| 388 // only affected by the layer's damaged area, which could be empty. |
| 389 gfx::Rect damage_rect = |
| 390 gfx::UnionRects(layer->update_rect(), layer->damage_rect()); |
| 391 damage_rect.Intersect(gfx::Rect(layer->bounds())); |
| 392 |
| 393 if (!damage_rect.IsEmpty()) { |
| 394 gfx::Rect damage_rect_in_target_space = MathUtil::MapEnclosingClippedRect( |
| 395 layer->DrawTransform(), damage_rect); |
| 396 damage_for_this_update_.Union(damage_rect_in_target_space); |
| 397 } |
384 } | 398 } |
385 | 399 |
386 // If the layer properties haven't changed, then the the target surface is | 400 // Property changes from animaiton will not be considered as damage from |
387 // only affected by the layer's damaged area, which could be empty. | 401 // contributing content. |
388 gfx::Rect damage_rect = | 402 if (layer_is_new || layer->LayerPropertyChangedOnly() || |
389 gfx::UnionRects(layer->update_rect(), layer->damage_rect()); | 403 !layer->update_rect().IsEmpty() || !layer->damage_rect().IsEmpty()) { |
390 damage_rect.Intersect(gfx::Rect(layer->bounds())); | 404 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 } | 405 } |
396 } | 406 } |
397 | 407 |
398 void DamageTracker::AccumulateDamageFromRenderSurface( | 408 void DamageTracker::AccumulateDamageFromRenderSurface( |
399 RenderSurfaceImpl* render_surface) { | 409 RenderSurfaceImpl* render_surface) { |
400 // There are two ways a "descendant surface" can damage regions of the "target | 410 // There are two ways a "descendant surface" can damage regions of the "target |
401 // surface": | 411 // surface": |
402 // 1. Property change: | 412 // 1. Property change: |
403 // - a surface's geometry can change because of | 413 // - a surface's geometry can change because of |
404 // - changes to descendants (i.e. the subtree) that affect the | 414 // - 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 | 459 // 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 | 460 // 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 | 461 // 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. | 462 // used for the blur in this layer this frame. |
453 const FilterOperations& background_filters = | 463 const FilterOperations& background_filters = |
454 render_surface->BackgroundFilters(); | 464 render_surface->BackgroundFilters(); |
455 if (background_filters.HasFilterThatMovesPixels()) { | 465 if (background_filters.HasFilterThatMovesPixels()) { |
456 ExpandDamageInsideRectWithFilters(surface_rect_in_target_space, | 466 ExpandDamageInsideRectWithFilters(surface_rect_in_target_space, |
457 background_filters); | 467 background_filters); |
458 } | 468 } |
| 469 |
| 470 // True if any changes from contributing render surface. |
| 471 has_damage_from_contributing_content_ |= !damage_for_this_update_.IsEmpty(); |
459 } | 472 } |
460 | 473 |
461 bool DamageTracker::DamageAccumulator::GetAsRect(gfx::Rect* rect) { | 474 bool DamageTracker::DamageAccumulator::GetAsRect(gfx::Rect* rect) { |
462 if (!is_valid_rect_) | 475 if (!is_valid_rect_) |
463 return false; | 476 return false; |
464 | 477 |
465 base::CheckedNumeric<int> width = right_; | 478 base::CheckedNumeric<int> width = right_; |
466 width -= x_; | 479 width -= x_; |
467 base::CheckedNumeric<int> height = bottom_; | 480 base::CheckedNumeric<int> height = bottom_; |
468 height -= y_; | 481 height -= y_; |
469 if (!width.IsValid() || !height.IsValid()) { | 482 if (!width.IsValid() || !height.IsValid()) { |
470 is_valid_rect_ = false; | 483 is_valid_rect_ = false; |
471 return false; | 484 return false; |
472 } | 485 } |
473 | 486 |
474 rect->set_x(x_); | 487 rect->set_x(x_); |
475 rect->set_y(y_); | 488 rect->set_y(y_); |
476 rect->set_width(width.ValueOrDie()); | 489 rect->set_width(width.ValueOrDie()); |
477 rect->set_height(height.ValueOrDie()); | 490 rect->set_height(height.ValueOrDie()); |
478 return true; | 491 return true; |
479 } | 492 } |
480 | 493 |
481 } // namespace cc | 494 } // namespace cc |
OLD | NEW |