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