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

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

Issue 2814273003: cc: Make DamageTracker use the effect tree and layer list (Closed)
Patch Set: Rebase Created 3 years, 8 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
« no previous file with comments | « cc/trees/damage_tracker.h ('k') | cc/trees/damage_tracker_unittest.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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/layer_tree_host_common.h" 18 #include "cc/trees/layer_tree_host_common.h"
18 #include "cc/trees/layer_tree_impl.h" 19 #include "cc/trees/layer_tree_impl.h"
19 #include "ui/gfx/geometry/rect_conversions.h" 20 #include "ui/gfx/geometry/rect_conversions.h"
20 21
21 namespace cc { 22 namespace cc {
22 23
23 std::unique_ptr<DamageTracker> DamageTracker::Create() { 24 std::unique_ptr<DamageTracker> DamageTracker::Create() {
24 return base::WrapUnique(new DamageTracker()); 25 return base::WrapUnique(new DamageTracker());
25 } 26 }
26 27
27 DamageTracker::DamageTracker() 28 DamageTracker::DamageTracker()
28 : mailboxId_(0) {} 29 : mailboxId_(0) {}
29 30
30 DamageTracker::~DamageTracker() {} 31 DamageTracker::~DamageTracker() {}
31 32
32 void DamageTracker::UpdateDamageTrackingState( 33 void DamageTracker::UpdateDamageTracking(
33 const LayerImplList& layer_list, 34 LayerTreeImpl* layer_tree_impl,
34 const RenderSurfaceImpl* target_surface, 35 const LayerImplList& render_surface_list) {
35 bool target_surface_property_changed_only_from_descendant,
36 const gfx::Rect& target_surface_content_rect,
37 LayerImpl* target_surface_mask_layer,
38 const FilterOperations& filters) {
39 // 36 //
40 // This function computes the "damage rect" of a target surface, and updates 37 // This function computes the "damage rect" of each target surface, and
41 // the state that is used to correctly track damage across frames. The damage 38 // updates the state that is used to correctly track damage across frames. The
42 // rect is the region of the surface that may have changed and needs to be 39 // damage rect is the region of the surface that may have changed and needs to
43 // redrawn. This can be used to scissor what is actually drawn, to save GPU 40 // be redrawn. This can be used to scissor what is actually drawn, to save GPU
44 // computation and bandwidth. 41 // computation and bandwidth.
45 // 42 //
46 // The surface's damage rect is computed as the union of all possible changes 43 // The surface's damage rect is computed as the union of all possible changes
47 // that have happened to the surface since the last frame was drawn. This 44 // that have happened to the surface since the last frame was drawn. This
48 // includes: 45 // includes:
49 // - any changes for existing layers/surfaces that contribute to the target 46 // - any changes for existing layers/surfaces that contribute to the target
50 // surface 47 // surface
51 // - layers/surfaces that existed in the previous frame, but no longer exist 48 // - layers/surfaces that existed in the previous frame, but no longer exist
52 // 49 //
53 // The basic algorithm for computing the damage region is as follows: 50 // The basic algorithm for computing the damage region is as follows:
54 // 51 //
55 // 1. compute damage caused by changes in active/new layers 52 // 1. compute damage caused by changes in contributing layers or surfaces
56 // for each layer in the layer_list: 53 // for each contributing layer or render surface:
57 // if the layer is actually a render_surface: 54 // add the layer's or surface's damage to the target surface.
58 // add the surface's damage to our target surface.
59 // else
60 // add the layer's damage to the target surface.
61 // 55 //
62 // 2. compute damage caused by the target surface's mask, if it exists. 56 // 2. compute damage caused by the target surface's mask, if it exists.
63 // 57 //
64 // 3. compute damage caused by old layers/surfaces that no longer exist 58 // 3. compute damage caused by old layers/surfaces that no longer exist
65 // for each leftover layer: 59 // for each leftover layer or render surface:
66 // add the old layer/surface bounds to the target surface damage. 60 // add the old layer/surface bounds to the target surface damage.
67 // 61 //
68 // 4. combine all partial damage rects to get the full damage rect. 62 // 4. combine all partial damage rects to get the full damage rect.
69 // 63 //
70 // Additional important points: 64 // Additional important points:
71 // 65 //
72 // - This algorithm is implicitly recursive; it assumes that descendant 66 // - This algorithm requires that descendant surfaces compute their damage
73 // surfaces have already computed their damage. 67 // before ancestor surfaces. Further, since contributing surfaces with
68 // background filters can expand the damage caused by contributors
69 // underneath them (that is, before them in draw order), the exact damage
70 // caused by these contributors must be computed before computing the damage
71 // caused by the contributing surface. This is implemented by visiting
72 // layers in draw order, computing the damage caused by each one to their
73 // target; during this walk, as soon as all of a surface's contributors have
74 // been visited, the surface's own damage is computed and then added to its
75 // target's accumulated damage.
74 // 76 //
75 // - Changes to layers/surfaces indicate "damage" to the target surface; If a 77 // - Changes to layers/surfaces indicate "damage" to the target surface; If a
76 // layer is not changed, it does NOT mean that the layer can skip drawing. 78 // layer is not changed, it does NOT mean that the layer can skip drawing.
77 // All layers that overlap the damaged region still need to be drawn. For 79 // All layers that overlap the damaged region still need to be drawn. For
78 // example, if a layer changed its opacity, then layers underneath must be 80 // example, if a layer changed its opacity, then layers underneath must be
79 // re-drawn as well, even if they did not change. 81 // re-drawn as well, even if they did not change.
80 // 82 //
81 // - If a layer/surface property changed, the old bounds and new bounds may 83 // - If a layer/surface property changed, the old bounds and new bounds may
82 // overlap... i.e. some of the exposed region may not actually be exposing 84 // overlap... i.e. some of the exposed region may not actually be exposing
83 // anything. But this does not artificially inflate the damage rect. If the 85 // anything. But this does not artificially inflate the damage rect. If the
(...skipping 13 matching lines...) Expand all
97 // layer changes or does not exist anymore, those regions are then 99 // layer changes or does not exist anymore, those regions are then
98 // exposed and damage the target surface. As the algorithm progresses, 100 // exposed and damage the target surface. As the algorithm progresses,
99 // entries are updated in the map until only leftover layers 101 // entries are updated in the map until only leftover layers
100 // that no longer exist stay marked not updated. 102 // that no longer exist stay marked not updated.
101 // 103 //
102 // 3. After the damage rect is computed, the leftover not marked regions 104 // 3. After the damage rect is computed, the leftover not marked regions
103 // in a map are used to compute are damaged by deleted layers and 105 // in a map are used to compute are damaged by deleted layers and
104 // erased from map. 106 // erased from map.
105 // 107 //
106 108
107 PrepareRectHistoryForUpdate(); 109 for (LayerImpl* layer : render_surface_list) {
110 layer->GetRenderSurface()->damage_tracker()->PrepareForUpdate();
111 }
112
113 EffectTree& effect_tree = layer_tree_impl->property_trees()->effect_tree;
114 int current_target_effect_id = EffectTree::kContentsRootNodeId;
115 DCHECK(effect_tree.GetRenderSurface(current_target_effect_id));
116 for (LayerImpl* layer : *layer_tree_impl) {
117 if (!layer->is_drawn_render_surface_layer_list_member())
118 continue;
119
120 int next_target_effect_id = layer->render_target_effect_tree_index();
121 if (next_target_effect_id != current_target_effect_id) {
122 int lowest_common_ancestor_id =
123 effect_tree.LowestCommonAncestorWithRenderSurface(
124 current_target_effect_id, next_target_effect_id);
125 while (current_target_effect_id != lowest_common_ancestor_id) {
126 // Moving to a non-descendant target surface. This implies that the
127 // current target doesn't have any more contributors, since only
128 // descendants can contribute to a target, and the each's target's
129 // content (including content contributed by descendants) is contiguous
130 // in draw order.
131 RenderSurfaceImpl* current_target =
132 effect_tree.GetRenderSurface(current_target_effect_id);
133 current_target->damage_tracker()->ComputeSurfaceDamage(current_target);
134 RenderSurfaceImpl* parent_target = current_target->render_target();
135 parent_target->damage_tracker()->AccumulateDamageFromRenderSurface(
136 current_target);
137 current_target_effect_id =
138 effect_tree.Node(current_target_effect_id)->target_id;
139 }
140 current_target_effect_id = next_target_effect_id;
141 }
142
143 RenderSurfaceImpl* target_surface = layer->render_target();
144
145 // We skip damage from the HUD layer because (a) the HUD layer damages the
146 // whole frame and (b) we don't want HUD layer damage to be shown by the
147 // HUD damage rect visualization.
148 if (layer != layer_tree_impl->hud_layer()) {
149 target_surface->damage_tracker()->AccumulateDamageFromLayer(layer);
150 }
151 }
152
153 DCHECK_GE(current_target_effect_id, EffectTree::kContentsRootNodeId);
154 RenderSurfaceImpl* current_target =
155 effect_tree.GetRenderSurface(current_target_effect_id);
156 while (true) {
157 current_target->damage_tracker()->ComputeSurfaceDamage(current_target);
158 if (current_target->EffectTreeIndex() == EffectTree::kContentsRootNodeId)
159 break;
160 RenderSurfaceImpl* next_target = current_target->render_target();
161 next_target->damage_tracker()->AccumulateDamageFromRenderSurface(
162 current_target);
163 current_target = next_target;
164 }
165 }
166
167 void DamageTracker::ComputeSurfaceDamage(RenderSurfaceImpl* render_surface) {
168 // All damage from contributing layers and surfaces must already have been
169 // added to damage_for_this_update_ through calls to AccumulateDamageFromLayer
170 // and AccumulateDamageFromRenderSurface.
171
108 // These functions cannot be bypassed with early-exits, even if we know what 172 // These functions cannot be bypassed with early-exits, even if we know what
109 // the damage will be for this frame, because we need to update the damage 173 // the damage will be for this frame, because we need to update the damage
110 // tracker state to correctly track the next frame. 174 // tracker state to correctly track the next frame.
111 DamageAccumulator damage_from_active_layers =
112 TrackDamageFromActiveLayers(layer_list, target_surface);
113 DamageAccumulator damage_from_surface_mask = 175 DamageAccumulator damage_from_surface_mask =
114 TrackDamageFromSurfaceMask(target_surface_mask_layer); 176 TrackDamageFromSurfaceMask(render_surface->MaskLayer());
115 DamageAccumulator damage_from_leftover_rects = TrackDamageFromLeftoverRects(); 177 DamageAccumulator damage_from_leftover_rects = TrackDamageFromLeftoverRects();
116 178
117 DamageAccumulator damage_for_this_update; 179 if (render_surface->SurfacePropertyChangedOnlyFromDescendant()) {
118 180 damage_for_this_update_ = DamageAccumulator();
119 if (target_surface_property_changed_only_from_descendant) { 181 damage_for_this_update_.Union(render_surface->content_rect());
120 damage_for_this_update.Union(target_surface_content_rect);
121 } else { 182 } else {
122 // TODO(shawnsingh): can we clamp this damage to the surface's content rect? 183 // TODO(shawnsingh): can we clamp this damage to the surface's content rect?
123 // (affects performance, but not correctness) 184 // (affects performance, but not correctness)
124 damage_for_this_update.Union(damage_from_active_layers); 185 damage_for_this_update_.Union(damage_from_surface_mask);
125 damage_for_this_update.Union(damage_from_surface_mask); 186 damage_for_this_update_.Union(damage_from_leftover_rects);
126 damage_for_this_update.Union(damage_from_leftover_rects);
127 187
128 gfx::Rect damage_rect; 188 gfx::Rect damage_rect;
129 bool is_rect_valid = damage_for_this_update.GetAsRect(&damage_rect); 189 bool is_rect_valid = damage_for_this_update_.GetAsRect(&damage_rect);
130 if (is_rect_valid) { 190 if (is_rect_valid) {
131 damage_rect = 191 damage_rect = render_surface->Filters().MapRect(
132 filters.MapRect(damage_rect, target_surface->SurfaceScale().matrix()); 192 damage_rect, render_surface->SurfaceScale().matrix());
133 damage_for_this_update = DamageAccumulator(); 193 damage_for_this_update_ = DamageAccumulator();
134 damage_for_this_update.Union(damage_rect); 194 damage_for_this_update_.Union(damage_rect);
135 } 195 }
136 } 196 }
137 197
138 // Damage accumulates until we are notified that we actually did draw on that 198 // Damage accumulates until we are notified that we actually did draw on that
139 // frame. 199 // frame.
140 current_damage_.Union(damage_for_this_update); 200 current_damage_.Union(damage_for_this_update_);
141 } 201 }
142 202
143 bool DamageTracker::GetDamageRectIfValid(gfx::Rect* rect) { 203 bool DamageTracker::GetDamageRectIfValid(gfx::Rect* rect) {
144 return current_damage_.GetAsRect(rect); 204 return current_damage_.GetAsRect(rect);
145 } 205 }
146 206
147 DamageTracker::LayerRectMapData& DamageTracker::RectDataForLayer( 207 DamageTracker::LayerRectMapData& DamageTracker::RectDataForLayer(
148 int layer_id, 208 int layer_id,
149 bool* layer_is_new) { 209 bool* layer_is_new) {
150 LayerRectMapData data(layer_id); 210 LayerRectMapData data(layer_id);
(...skipping 19 matching lines...) Expand all
170 rect_history_for_surfaces_.end(), data); 230 rect_history_for_surfaces_.end(), data);
171 231
172 if (it == rect_history_for_surfaces_.end() || it->surface_id_ != surface_id) { 232 if (it == rect_history_for_surfaces_.end() || it->surface_id_ != surface_id) {
173 *surface_is_new = true; 233 *surface_is_new = true;
174 it = rect_history_for_surfaces_.insert(it, data); 234 it = rect_history_for_surfaces_.insert(it, data);
175 } 235 }
176 236
177 return *it; 237 return *it;
178 } 238 }
179 239
180 DamageTracker::DamageAccumulator DamageTracker::TrackDamageFromActiveLayers(
181 const LayerImplList& layer_list,
182 const RenderSurfaceImpl* target_surface) {
183 DamageAccumulator damage;
184
185 for (size_t layer_index = 0; layer_index < layer_list.size(); ++layer_index) {
186 // Visit layers in back-to-front order.
187 LayerImpl* layer = layer_list[layer_index];
188
189 // We skip damage from the HUD layer because (a) the HUD layer damages the
190 // whole frame and (b) we don't want HUD layer damage to be shown by the
191 // HUD damage rect visualization.
192 if (layer == layer->layer_tree_impl()->hud_layer())
193 continue;
194
195 RenderSurfaceImpl* render_surface = layer->GetRenderSurface();
196 if (render_surface && render_surface != target_surface)
197 ExtendDamageForRenderSurface(render_surface, &damage);
198 else
199 ExtendDamageForLayer(layer, &damage);
200 }
201
202 return damage;
203 }
204
205 DamageTracker::DamageAccumulator DamageTracker::TrackDamageFromSurfaceMask( 240 DamageTracker::DamageAccumulator DamageTracker::TrackDamageFromSurfaceMask(
206 LayerImpl* target_surface_mask_layer) { 241 LayerImpl* target_surface_mask_layer) {
207 DamageAccumulator damage; 242 DamageAccumulator damage;
208 243
209 if (!target_surface_mask_layer) 244 if (!target_surface_mask_layer)
210 return damage; 245 return damage;
211 246
212 // Currently, if there is any change to the mask, we choose to damage the 247 // Currently, if there is any change to the mask, we choose to damage the
213 // entire surface. This could potentially be optimized later, but it is not 248 // entire surface. This could potentially be optimized later, but it is not
214 // expected to be a common case. 249 // expected to be a common case.
215 if (target_surface_mask_layer->LayerPropertyChanged() || 250 if (target_surface_mask_layer->LayerPropertyChanged() ||
216 !target_surface_mask_layer->update_rect().IsEmpty()) { 251 !target_surface_mask_layer->update_rect().IsEmpty()) {
217 damage.Union(gfx::Rect(target_surface_mask_layer->bounds())); 252 damage.Union(gfx::Rect(target_surface_mask_layer->bounds()));
218 } 253 }
219 254
220 return damage; 255 return damage;
221 } 256 }
222 257
223 void DamageTracker::PrepareRectHistoryForUpdate() { 258 void DamageTracker::PrepareForUpdate() {
224 mailboxId_++; 259 mailboxId_++;
260 damage_for_this_update_ = DamageAccumulator();
225 } 261 }
226 262
227 DamageTracker::DamageAccumulator DamageTracker::TrackDamageFromLeftoverRects() { 263 DamageTracker::DamageAccumulator DamageTracker::TrackDamageFromLeftoverRects() {
228 // After computing damage for all active layers, any leftover items in the 264 // After computing damage for all active layers, any leftover items in the
229 // current rect history correspond to layers/surfaces that no longer exist. 265 // current rect history correspond to layers/surfaces that no longer exist.
230 // So, these regions are now exposed on the target surface. 266 // So, these regions are now exposed on the target surface.
231 267
232 DamageAccumulator damage; 268 DamageAccumulator damage;
233 SortedRectMapForLayers::iterator layer_cur_pos = 269 SortedRectMapForLayers::iterator layer_cur_pos =
234 rect_history_for_layers_.begin(); 270 rect_history_for_layers_.begin();
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after
285 if (rect_history_for_surfaces_.capacity() > 321 if (rect_history_for_surfaces_.capacity() >
286 rect_history_for_surfaces_.size() * 4) 322 rect_history_for_surfaces_.size() * 4)
287 SortedRectMapForSurfaces(rect_history_for_surfaces_) 323 SortedRectMapForSurfaces(rect_history_for_surfaces_)
288 .swap(rect_history_for_surfaces_); 324 .swap(rect_history_for_surfaces_);
289 325
290 return damage; 326 return damage;
291 } 327 }
292 328
293 void DamageTracker::ExpandDamageInsideRectWithFilters( 329 void DamageTracker::ExpandDamageInsideRectWithFilters(
294 const gfx::Rect& pre_filter_rect, 330 const gfx::Rect& pre_filter_rect,
295 const FilterOperations& filters, 331 const FilterOperations& filters) {
296 DamageAccumulator* damage) {
297 gfx::Rect damage_rect; 332 gfx::Rect damage_rect;
298 bool is_valid_rect = damage->GetAsRect(&damage_rect); 333 bool is_valid_rect = damage_for_this_update_.GetAsRect(&damage_rect);
299 // If the input isn't a valid rect, then there is no point in trying to make 334 // If the damage accumulated so far isn't a valid rect, then there is no point
300 // it bigger. 335 // in trying to make it bigger.
301 if (!is_valid_rect) 336 if (!is_valid_rect)
302 return; 337 return;
303 338
304 // Compute the pixels in the background of the surface that could be affected 339 // Compute the pixels in the background of the surface that could be affected
305 // by the damage in the content below. 340 // by the damage in the content below.
306 gfx::Rect expanded_damage_rect = filters.MapRect(damage_rect, SkMatrix::I()); 341 gfx::Rect expanded_damage_rect = filters.MapRect(damage_rect, SkMatrix::I());
307 342
308 // Restrict it to the rectangle in which the background filter is shown. 343 // Restrict it to the rectangle in which the background filter is shown.
309 expanded_damage_rect.Intersect(pre_filter_rect); 344 expanded_damage_rect.Intersect(pre_filter_rect);
310 345
311 damage->Union(expanded_damage_rect); 346 damage_for_this_update_.Union(expanded_damage_rect);
312 } 347 }
313 348
314 void DamageTracker::ExtendDamageForLayer(LayerImpl* layer, 349 void DamageTracker::AccumulateDamageFromLayer(LayerImpl* layer) {
315 DamageAccumulator* target_damage) {
316 // There are two ways that a layer can damage a region of the target surface: 350 // There are two ways that a layer can damage a region of the target surface:
317 // 1. Property change (e.g. opacity, position, transforms): 351 // 1. Property change (e.g. opacity, position, transforms):
318 // - the entire region of the layer itself damages the surface. 352 // - the entire region of the layer itself damages the surface.
319 // - the old layer region also damages the surface, because this region 353 // - the old layer region also damages the surface, because this region
320 // is now exposed. 354 // is now exposed.
321 // - note that in many cases the old and new layer rects may overlap, 355 // - note that in many cases the old and new layer rects may overlap,
322 // which is fine. 356 // which is fine.
323 // 357 //
324 // 2. Repaint/update: If a region of the layer that was repainted/updated, 358 // 2. Repaint/update: If a region of the layer that was repainted/updated,
325 // that region damages the surface. 359 // that region damages the surface.
326 // 360 //
327 // Property changes take priority over update rects. 361 // Property changes take priority over update rects.
328 // 362 //
329 // This method is called when we want to consider how a layer contributes to 363 // This method is called when we want to consider how a layer contributes to
330 // its target RenderSurface, even if that layer owns the target RenderSurface 364 // its target RenderSurface, even if that layer owns the target RenderSurface
331 // itself. To consider how a layer's target surface contributes to the 365 // itself. To consider how a layer's target surface contributes to the
332 // ancestor surface, ExtendDamageForRenderSurface() must be called instead. 366 // ancestor surface, ExtendDamageForRenderSurface() must be called instead.
333 367
334 bool layer_is_new = false; 368 bool layer_is_new = false;
335 LayerRectMapData& data = RectDataForLayer(layer->id(), &layer_is_new); 369 LayerRectMapData& data = RectDataForLayer(layer->id(), &layer_is_new);
336 gfx::Rect old_rect_in_target_space = data.rect_; 370 gfx::Rect old_rect_in_target_space = data.rect_;
337 371
338 gfx::Rect rect_in_target_space = layer->GetEnclosingRectInTargetSpace(); 372 gfx::Rect rect_in_target_space = layer->GetEnclosingRectInTargetSpace();
339 data.Update(rect_in_target_space, mailboxId_); 373 data.Update(rect_in_target_space, mailboxId_);
340 374
341 if (layer_is_new || layer->LayerPropertyChanged()) { 375 if (layer_is_new || layer->LayerPropertyChanged()) {
342 // If a layer is new or has changed, then its entire layer rect affects the 376 // If a layer is new or has changed, then its entire layer rect affects the
343 // target surface. 377 // target surface.
344 target_damage->Union(rect_in_target_space); 378 damage_for_this_update_.Union(rect_in_target_space);
345 379
346 // The layer's old region is now exposed on the target surface, too. 380 // The layer's old region is now exposed on the target surface, too.
347 // Note old_rect_in_target_space is already in target space. 381 // Note old_rect_in_target_space is already in target space.
348 target_damage->Union(old_rect_in_target_space); 382 damage_for_this_update_.Union(old_rect_in_target_space);
349 return; 383 return;
350 } 384 }
351 385
352 // If the layer properties haven't changed, then the the target surface is 386 // If the layer properties haven't changed, then the the target surface is
353 // only affected by the layer's damaged area, which could be empty. 387 // only affected by the layer's damaged area, which could be empty.
354 gfx::Rect damage_rect = 388 gfx::Rect damage_rect =
355 gfx::UnionRects(layer->update_rect(), layer->damage_rect()); 389 gfx::UnionRects(layer->update_rect(), layer->damage_rect());
356 damage_rect.Intersect(gfx::Rect(layer->bounds())); 390 damage_rect.Intersect(gfx::Rect(layer->bounds()));
357 if (!damage_rect.IsEmpty()) { 391 if (!damage_rect.IsEmpty()) {
358 gfx::Rect damage_rect_in_target_space = 392 gfx::Rect damage_rect_in_target_space =
359 MathUtil::MapEnclosingClippedRect(layer->DrawTransform(), damage_rect); 393 MathUtil::MapEnclosingClippedRect(layer->DrawTransform(), damage_rect);
360 target_damage->Union(damage_rect_in_target_space); 394 damage_for_this_update_.Union(damage_rect_in_target_space);
361 } 395 }
362 } 396 }
363 397
364 void DamageTracker::ExtendDamageForRenderSurface( 398 void DamageTracker::AccumulateDamageFromRenderSurface(
365 RenderSurfaceImpl* render_surface, 399 RenderSurfaceImpl* render_surface) {
366 DamageAccumulator* target_damage) {
367 // 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
368 // surface": 401 // surface":
369 // 1. Property change: 402 // 1. Property change:
370 // - a surface's geometry can change because of 403 // - a surface's geometry can change because of
371 // - changes to descendants (i.e. the subtree) that affect the 404 // - changes to descendants (i.e. the subtree) that affect the
372 // surface's content rect 405 // surface's content rect
373 // - changes to ancestor layers that propagate their property 406 // - changes to ancestor layers that propagate their property
374 // changes to their entire subtree. 407 // changes to their entire subtree.
375 // - just like layers, both the old surface rect and new surface rect 408 // - just like layers, both the old surface rect and new surface rect
376 // will damage the target surface in this case. 409 // will damage the target surface in this case.
377 // 410 //
378 // 2. Damage rect: This surface may have been damaged by its own layer_list 411 // 2. Damage rect: This surface may have been damaged by its own layer_list
379 // as well, and that damage should propagate to the target surface. 412 // as well, and that damage should propagate to the target surface.
380 // 413 //
381 414
382 bool surface_is_new = false; 415 bool surface_is_new = false;
383 SurfaceRectMapData& data = 416 SurfaceRectMapData& data =
384 RectDataForSurface(render_surface->id(), &surface_is_new); 417 RectDataForSurface(render_surface->id(), &surface_is_new);
385 gfx::Rect old_surface_rect = data.rect_; 418 gfx::Rect old_surface_rect = data.rect_;
386 419
387 gfx::Rect surface_rect_in_target_space = 420 gfx::Rect surface_rect_in_target_space =
388 gfx::ToEnclosingRect(render_surface->DrawableContentRect()); 421 gfx::ToEnclosingRect(render_surface->DrawableContentRect());
389 data.Update(surface_rect_in_target_space, mailboxId_); 422 data.Update(surface_rect_in_target_space, mailboxId_);
390 423
391 if (surface_is_new || render_surface->SurfacePropertyChanged()) { 424 if (surface_is_new || render_surface->SurfacePropertyChanged()) {
392 // The entire surface contributes damage. 425 // The entire surface contributes damage.
393 target_damage->Union(surface_rect_in_target_space); 426 damage_for_this_update_.Union(surface_rect_in_target_space);
394 427
395 // The surface's old region is now exposed on the target surface, too. 428 // The surface's old region is now exposed on the target surface, too.
396 target_damage->Union(old_surface_rect); 429 damage_for_this_update_.Union(old_surface_rect);
397 } else { 430 } else {
398 // Only the surface's damage_rect will damage the target surface. 431 // Only the surface's damage_rect will damage the target surface.
399 gfx::Rect damage_rect_in_local_space; 432 gfx::Rect damage_rect_in_local_space;
400 bool is_valid_rect = render_surface->damage_tracker()->GetDamageRectIfValid( 433 bool is_valid_rect = render_surface->damage_tracker()->GetDamageRectIfValid(
401 &damage_rect_in_local_space); 434 &damage_rect_in_local_space);
402 if (is_valid_rect && !damage_rect_in_local_space.IsEmpty()) { 435 if (is_valid_rect && !damage_rect_in_local_space.IsEmpty()) {
403 // If there was damage, transform it to target space, and possibly 436 // If there was damage, transform it to target space, and possibly
404 // contribute its reflection if needed. 437 // contribute its reflection if needed.
405 const gfx::Transform& draw_transform = render_surface->draw_transform(); 438 const gfx::Transform& draw_transform = render_surface->draw_transform();
406 gfx::Rect damage_rect_in_target_space = MathUtil::MapEnclosingClippedRect( 439 gfx::Rect damage_rect_in_target_space = MathUtil::MapEnclosingClippedRect(
407 draw_transform, damage_rect_in_local_space); 440 draw_transform, damage_rect_in_local_space);
408 target_damage->Union(damage_rect_in_target_space); 441 damage_for_this_update_.Union(damage_rect_in_target_space);
409 } else if (!is_valid_rect) { 442 } else if (!is_valid_rect) {
410 target_damage->Union(surface_rect_in_target_space); 443 damage_for_this_update_.Union(surface_rect_in_target_space);
411 } 444 }
412 } 445 }
413 446
414 // If the layer has a background filter, this may cause pixels in our surface 447 // If the layer has a background filter, this may cause pixels in our surface
415 // to be expanded, so we will need to expand any damage at or below this 448 // to be expanded, so we will need to expand any damage at or below this
416 // 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
417 // 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
418 // 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
419 // used for the blur in this layer this frame. 452 // used for the blur in this layer this frame.
420 const FilterOperations& background_filters = 453 const FilterOperations& background_filters =
421 render_surface->BackgroundFilters(); 454 render_surface->BackgroundFilters();
422 if (background_filters.HasFilterThatMovesPixels()) { 455 if (background_filters.HasFilterThatMovesPixels()) {
423 ExpandDamageInsideRectWithFilters(surface_rect_in_target_space, 456 ExpandDamageInsideRectWithFilters(surface_rect_in_target_space,
424 background_filters, target_damage); 457 background_filters);
425 } 458 }
426 } 459 }
427 460
428 bool DamageTracker::DamageAccumulator::GetAsRect(gfx::Rect* rect) { 461 bool DamageTracker::DamageAccumulator::GetAsRect(gfx::Rect* rect) {
429 if (!is_valid_rect_) 462 if (!is_valid_rect_)
430 return false; 463 return false;
431 464
432 base::CheckedNumeric<int> width = right_; 465 base::CheckedNumeric<int> width = right_;
433 width -= x_; 466 width -= x_;
434 base::CheckedNumeric<int> height = bottom_; 467 base::CheckedNumeric<int> height = bottom_;
435 height -= y_; 468 height -= y_;
436 if (!width.IsValid() || !height.IsValid()) { 469 if (!width.IsValid() || !height.IsValid()) {
437 is_valid_rect_ = false; 470 is_valid_rect_ = false;
438 return false; 471 return false;
439 } 472 }
440 473
441 rect->set_x(x_); 474 rect->set_x(x_);
442 rect->set_y(y_); 475 rect->set_y(y_);
443 rect->set_width(width.ValueOrDie()); 476 rect->set_width(width.ValueOrDie());
444 rect->set_height(height.ValueOrDie()); 477 rect->set_height(height.ValueOrDie());
445 return true; 478 return true;
446 } 479 }
447 480
448 } // namespace cc 481 } // namespace cc
OLDNEW
« no previous file with comments | « cc/trees/damage_tracker.h ('k') | cc/trees/damage_tracker_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698