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