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

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

Issue 2873593002: Force use of and cache render surface. (Closed)
Patch Set: Fix compile error. 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 165 matching lines...) Expand 10 before | Expand all | Expand 10 after
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
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
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698