| 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 |