Chromium Code Reviews| 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 |
| (...skipping 11 matching lines...) Expand all Loading... | |
| 22 | 22 |
| 23 std::unique_ptr<DamageTracker> DamageTracker::Create() { | 23 std::unique_ptr<DamageTracker> DamageTracker::Create() { |
| 24 return base::WrapUnique(new DamageTracker()); | 24 return base::WrapUnique(new DamageTracker()); |
| 25 } | 25 } |
| 26 | 26 |
| 27 DamageTracker::DamageTracker() | 27 DamageTracker::DamageTracker() |
| 28 : mailboxId_(0) {} | 28 : mailboxId_(0) {} |
| 29 | 29 |
| 30 DamageTracker::~DamageTracker() {} | 30 DamageTracker::~DamageTracker() {} |
| 31 | 31 |
| 32 static inline void ExpandDamageRectInsideRectWithFilters( | |
| 33 gfx::Rect* damage_rect, | |
| 34 const gfx::Rect& pre_filter_rect, | |
| 35 const FilterOperations& filters) { | |
| 36 // Compute the pixels in the background of the surface that could be affected | |
| 37 // by the damage in the content below. | |
| 38 gfx::Rect expanded_damage_rect = filters.MapRect(*damage_rect, SkMatrix::I()); | |
| 39 | |
| 40 // Restrict it to the rectangle in which the background filter is shown. | |
| 41 expanded_damage_rect.Intersect(pre_filter_rect); | |
| 42 | |
| 43 damage_rect->Union(expanded_damage_rect); | |
| 44 } | |
| 45 | |
| 46 void DamageTracker::UpdateDamageTrackingState( | 32 void DamageTracker::UpdateDamageTrackingState( |
| 47 const LayerImplList& layer_list, | 33 const LayerImplList& layer_list, |
| 48 const RenderSurfaceImpl* target_surface, | 34 const RenderSurfaceImpl* target_surface, |
| 49 bool target_surface_property_changed_only_from_descendant, | 35 bool target_surface_property_changed_only_from_descendant, |
| 50 const gfx::Rect& target_surface_content_rect, | 36 const gfx::Rect& target_surface_content_rect, |
| 51 LayerImpl* target_surface_mask_layer, | 37 LayerImpl* target_surface_mask_layer, |
| 52 const FilterOperations& filters) { | 38 const FilterOperations& filters) { |
| 53 // | 39 // |
| 54 // This function computes the "damage rect" of a target surface, and updates | 40 // This function computes the "damage rect" of a target surface, and updates |
| 55 // the state that is used to correctly track damage across frames. The damage | 41 // the state that is used to correctly track damage across frames. The damage |
| (...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 115 // | 101 // |
| 116 // 3. After the damage rect is computed, the leftover not marked regions | 102 // 3. After the damage rect is computed, the leftover not marked regions |
| 117 // in a map are used to compute are damaged by deleted layers and | 103 // in a map are used to compute are damaged by deleted layers and |
| 118 // erased from map. | 104 // erased from map. |
| 119 // | 105 // |
| 120 | 106 |
| 121 PrepareRectHistoryForUpdate(); | 107 PrepareRectHistoryForUpdate(); |
| 122 // These functions cannot be bypassed with early-exits, even if we know what | 108 // These functions cannot be bypassed with early-exits, even if we know what |
| 123 // the damage will be for this frame, because we need to update the damage | 109 // the damage will be for this frame, because we need to update the damage |
| 124 // tracker state to correctly track the next frame. | 110 // tracker state to correctly track the next frame. |
| 125 gfx::Rect damage_from_active_layers = | 111 DamageAccumulator damage_from_active_layers = |
| 126 TrackDamageFromActiveLayers(layer_list, target_surface); | 112 TrackDamageFromActiveLayers(layer_list, target_surface); |
| 127 gfx::Rect damage_from_surface_mask = | 113 DamageAccumulator damage_from_surface_mask = |
| 128 TrackDamageFromSurfaceMask(target_surface_mask_layer); | 114 TrackDamageFromSurfaceMask(target_surface_mask_layer); |
| 129 gfx::Rect damage_from_leftover_rects = TrackDamageFromLeftoverRects(); | 115 DamageAccumulator damage_from_leftover_rects = TrackDamageFromLeftoverRects(); |
| 130 | 116 |
| 131 gfx::Rect damage_rect_for_this_update; | 117 DamageAccumulator damage_for_this_update; |
| 132 | 118 |
| 133 if (target_surface_property_changed_only_from_descendant) { | 119 if (target_surface_property_changed_only_from_descendant) { |
| 134 damage_rect_for_this_update = target_surface_content_rect; | 120 damage_for_this_update.Union(target_surface_content_rect); |
| 135 } else { | 121 } else { |
| 136 // TODO(shawnsingh): can we clamp this damage to the surface's content rect? | 122 // TODO(shawnsingh): can we clamp this damage to the surface's content rect? |
| 137 // (affects performance, but not correctness) | 123 // (affects performance, but not correctness) |
| 138 damage_rect_for_this_update = damage_from_active_layers; | 124 damage_for_this_update.Union(damage_from_active_layers); |
| 139 damage_rect_for_this_update.Union(damage_from_surface_mask); | 125 damage_for_this_update.Union(damage_from_surface_mask); |
| 140 damage_rect_for_this_update.Union(damage_from_leftover_rects); | 126 damage_for_this_update.Union(damage_from_leftover_rects); |
| 141 damage_rect_for_this_update = | 127 |
| 142 filters.MapRect(damage_rect_for_this_update, | 128 gfx::Rect damage_rect; |
| 143 target_surface->FiltersTransform().matrix()); | 129 bool is_rect_valid = damage_for_this_update.GetAsRect(&damage_rect); |
| 130 if (is_rect_valid) { | |
| 131 damage_rect = filters.MapRect( | |
| 132 damage_rect, target_surface->FiltersTransform().matrix()); | |
| 133 damage_for_this_update = DamageAccumulator(); | |
| 134 damage_for_this_update.Union(damage_rect); | |
| 135 } | |
| 144 } | 136 } |
| 145 | 137 |
| 146 // Damage accumulates until we are notified that we actually did draw on that | 138 // Damage accumulates until we are notified that we actually did draw on that |
| 147 // frame. | 139 // frame. |
| 148 current_damage_rect_.Union(damage_rect_for_this_update); | 140 current_damage_.Union(damage_for_this_update); |
| 141 } | |
| 142 | |
| 143 bool DamageTracker::ShouldDamageEverything() { | |
| 144 gfx::Rect rect; | |
| 145 return !current_damage_.GetAsRect(&rect); | |
|
danakj
2017/01/13 23:17:58
I thot it a bit odd this computes a rect to throw
vmpstr
2017/01/19 23:08:27
Done. I with with bool GetRect(Rect*) type of func
| |
| 146 } | |
| 147 | |
| 148 gfx::Rect DamageTracker::CurrentDamageRect() { | |
| 149 gfx::Rect rect; | |
| 150 current_damage_.GetAsRect(&rect); | |
| 151 return rect; | |
| 149 } | 152 } |
| 150 | 153 |
| 151 DamageTracker::LayerRectMapData& DamageTracker::RectDataForLayer( | 154 DamageTracker::LayerRectMapData& DamageTracker::RectDataForLayer( |
| 152 int layer_id, | 155 int layer_id, |
| 153 bool* layer_is_new) { | 156 bool* layer_is_new) { |
| 154 LayerRectMapData data(layer_id); | 157 LayerRectMapData data(layer_id); |
| 155 | 158 |
| 156 SortedRectMapForLayers::iterator it = std::lower_bound( | 159 SortedRectMapForLayers::iterator it = std::lower_bound( |
| 157 rect_history_for_layers_.begin(), rect_history_for_layers_.end(), data); | 160 rect_history_for_layers_.begin(), rect_history_for_layers_.end(), data); |
| 158 | 161 |
| (...skipping 15 matching lines...) Expand all Loading... | |
| 174 rect_history_for_surfaces_.end(), data); | 177 rect_history_for_surfaces_.end(), data); |
| 175 | 178 |
| 176 if (it == rect_history_for_surfaces_.end() || it->surface_id_ != surface_id) { | 179 if (it == rect_history_for_surfaces_.end() || it->surface_id_ != surface_id) { |
| 177 *surface_is_new = true; | 180 *surface_is_new = true; |
| 178 it = rect_history_for_surfaces_.insert(it, data); | 181 it = rect_history_for_surfaces_.insert(it, data); |
| 179 } | 182 } |
| 180 | 183 |
| 181 return *it; | 184 return *it; |
| 182 } | 185 } |
| 183 | 186 |
| 184 gfx::Rect DamageTracker::TrackDamageFromActiveLayers( | 187 DamageTracker::DamageAccumulator DamageTracker::TrackDamageFromActiveLayers( |
| 185 const LayerImplList& layer_list, | 188 const LayerImplList& layer_list, |
| 186 const RenderSurfaceImpl* target_surface) { | 189 const RenderSurfaceImpl* target_surface) { |
| 187 gfx::Rect damage_rect; | 190 DamageAccumulator damage; |
| 188 | 191 |
| 189 for (size_t layer_index = 0; layer_index < layer_list.size(); ++layer_index) { | 192 for (size_t layer_index = 0; layer_index < layer_list.size(); ++layer_index) { |
| 190 // Visit layers in back-to-front order. | 193 // Visit layers in back-to-front order. |
| 191 LayerImpl* layer = layer_list[layer_index]; | 194 LayerImpl* layer = layer_list[layer_index]; |
| 192 | 195 |
| 193 // We skip damage from the HUD layer because (a) the HUD layer damages the | 196 // We skip damage from the HUD layer because (a) the HUD layer damages the |
| 194 // whole frame and (b) we don't want HUD layer damage to be shown by the | 197 // whole frame and (b) we don't want HUD layer damage to be shown by the |
| 195 // HUD damage rect visualization. | 198 // HUD damage rect visualization. |
| 196 if (layer == layer->layer_tree_impl()->hud_layer()) | 199 if (layer == layer->layer_tree_impl()->hud_layer()) |
| 197 continue; | 200 continue; |
| 198 | 201 |
| 199 if (layer->render_surface() && layer->render_surface() != target_surface) | 202 if (layer->render_surface() && layer->render_surface() != target_surface) |
| 200 ExtendDamageForRenderSurface(layer->render_surface(), &damage_rect); | 203 ExtendDamageForRenderSurface(layer->render_surface(), &damage); |
| 201 else | 204 else |
| 202 ExtendDamageForLayer(layer, &damage_rect); | 205 ExtendDamageForLayer(layer, &damage); |
| 203 } | 206 } |
| 204 | 207 |
| 205 return damage_rect; | 208 return damage; |
| 206 } | 209 } |
| 207 | 210 |
| 208 gfx::Rect DamageTracker::TrackDamageFromSurfaceMask( | 211 DamageTracker::DamageAccumulator DamageTracker::TrackDamageFromSurfaceMask( |
| 209 LayerImpl* target_surface_mask_layer) { | 212 LayerImpl* target_surface_mask_layer) { |
| 210 gfx::Rect damage_rect; | 213 DamageAccumulator damage; |
| 211 | 214 |
| 212 if (!target_surface_mask_layer) | 215 if (!target_surface_mask_layer) |
| 213 return damage_rect; | 216 return damage; |
| 214 | 217 |
| 215 // Currently, if there is any change to the mask, we choose to damage the | 218 // Currently, if there is any change to the mask, we choose to damage the |
| 216 // entire surface. This could potentially be optimized later, but it is not | 219 // entire surface. This could potentially be optimized later, but it is not |
| 217 // expected to be a common case. | 220 // expected to be a common case. |
| 218 if (target_surface_mask_layer->LayerPropertyChanged() || | 221 if (target_surface_mask_layer->LayerPropertyChanged() || |
| 219 !target_surface_mask_layer->update_rect().IsEmpty()) { | 222 !target_surface_mask_layer->update_rect().IsEmpty()) { |
| 220 damage_rect = gfx::Rect(target_surface_mask_layer->bounds()); | 223 damage.Union(gfx::Rect(target_surface_mask_layer->bounds())); |
| 221 } | 224 } |
| 222 | 225 |
| 223 return damage_rect; | 226 return damage; |
| 224 } | 227 } |
| 225 | 228 |
| 226 void DamageTracker::PrepareRectHistoryForUpdate() { | 229 void DamageTracker::PrepareRectHistoryForUpdate() { |
| 227 mailboxId_++; | 230 mailboxId_++; |
| 228 } | 231 } |
| 229 | 232 |
| 230 gfx::Rect DamageTracker::TrackDamageFromLeftoverRects() { | 233 DamageTracker::DamageAccumulator DamageTracker::TrackDamageFromLeftoverRects() { |
| 231 // After computing damage for all active layers, any leftover items in the | 234 // After computing damage for all active layers, any leftover items in the |
| 232 // current rect history correspond to layers/surfaces that no longer exist. | 235 // current rect history correspond to layers/surfaces that no longer exist. |
| 233 // So, these regions are now exposed on the target surface. | 236 // So, these regions are now exposed on the target surface. |
| 234 | 237 |
| 235 gfx::Rect damage_rect; | 238 DamageAccumulator damage; |
| 236 SortedRectMapForLayers::iterator layer_cur_pos = | 239 SortedRectMapForLayers::iterator layer_cur_pos = |
| 237 rect_history_for_layers_.begin(); | 240 rect_history_for_layers_.begin(); |
| 238 SortedRectMapForLayers::iterator layer_copy_pos = layer_cur_pos; | 241 SortedRectMapForLayers::iterator layer_copy_pos = layer_cur_pos; |
| 239 SortedRectMapForSurfaces::iterator surface_cur_pos = | 242 SortedRectMapForSurfaces::iterator surface_cur_pos = |
| 240 rect_history_for_surfaces_.begin(); | 243 rect_history_for_surfaces_.begin(); |
| 241 SortedRectMapForSurfaces::iterator surface_copy_pos = surface_cur_pos; | 244 SortedRectMapForSurfaces::iterator surface_copy_pos = surface_cur_pos; |
| 242 | 245 |
| 243 // Loop below basically implements std::remove_if loop with and extra | 246 // Loop below basically implements std::remove_if loop with and extra |
| 244 // processing (adding deleted rect to damage_rect) for deleted items. | 247 // processing (adding deleted rect to damage) for deleted items. |
| 245 // cur_pos iterator runs through all elements of the vector, but copy_pos | 248 // cur_pos iterator runs through all elements of the vector, but copy_pos |
| 246 // always points to the element after the last not deleted element. If new | 249 // always points to the element after the last not deleted element. If new |
| 247 // not deleted element found then it is copied to the *copy_pos and copy_pos | 250 // not deleted element found then it is copied to the *copy_pos and copy_pos |
| 248 // moved to the next position. | 251 // moved to the next position. |
| 249 // If there are no deleted elements then copy_pos iterator is in sync with | 252 // If there are no deleted elements then copy_pos iterator is in sync with |
| 250 // cur_pos and no copy happens. | 253 // cur_pos and no copy happens. |
| 251 while (layer_cur_pos < rect_history_for_layers_.end()) { | 254 while (layer_cur_pos < rect_history_for_layers_.end()) { |
| 252 if (layer_cur_pos->mailboxId_ == mailboxId_) { | 255 if (layer_cur_pos->mailboxId_ == mailboxId_) { |
| 253 if (layer_cur_pos != layer_copy_pos) | 256 if (layer_cur_pos != layer_copy_pos) |
| 254 *layer_copy_pos = *layer_cur_pos; | 257 *layer_copy_pos = *layer_cur_pos; |
| 255 | 258 |
| 256 ++layer_copy_pos; | 259 ++layer_copy_pos; |
| 257 } else { | 260 } else { |
| 258 damage_rect.Union(layer_cur_pos->rect_); | 261 damage.Union(layer_cur_pos->rect_); |
| 259 } | 262 } |
| 260 | 263 |
| 261 ++layer_cur_pos; | 264 ++layer_cur_pos; |
| 262 } | 265 } |
| 263 | 266 |
| 264 while (surface_cur_pos < rect_history_for_surfaces_.end()) { | 267 while (surface_cur_pos < rect_history_for_surfaces_.end()) { |
| 265 if (surface_cur_pos->mailboxId_ == mailboxId_) { | 268 if (surface_cur_pos->mailboxId_ == mailboxId_) { |
| 266 if (surface_cur_pos != surface_copy_pos) | 269 if (surface_cur_pos != surface_copy_pos) |
| 267 *surface_copy_pos = *surface_cur_pos; | 270 *surface_copy_pos = *surface_cur_pos; |
| 268 | 271 |
| 269 ++surface_copy_pos; | 272 ++surface_copy_pos; |
| 270 } else { | 273 } else { |
| 271 damage_rect.Union(surface_cur_pos->rect_); | 274 damage.Union(surface_cur_pos->rect_); |
| 272 } | 275 } |
| 273 | 276 |
| 274 ++surface_cur_pos; | 277 ++surface_cur_pos; |
| 275 } | 278 } |
| 276 | 279 |
| 277 if (layer_copy_pos != rect_history_for_layers_.end()) | 280 if (layer_copy_pos != rect_history_for_layers_.end()) |
| 278 rect_history_for_layers_.erase(layer_copy_pos, | 281 rect_history_for_layers_.erase(layer_copy_pos, |
| 279 rect_history_for_layers_.end()); | 282 rect_history_for_layers_.end()); |
| 280 if (surface_copy_pos != rect_history_for_surfaces_.end()) | 283 if (surface_copy_pos != rect_history_for_surfaces_.end()) |
| 281 rect_history_for_surfaces_.erase(surface_copy_pos, | 284 rect_history_for_surfaces_.erase(surface_copy_pos, |
| 282 rect_history_for_surfaces_.end()); | 285 rect_history_for_surfaces_.end()); |
| 283 | 286 |
| 284 // If the vector has excessive storage, shrink it | 287 // If the vector has excessive storage, shrink it |
| 285 if (rect_history_for_layers_.capacity() > rect_history_for_layers_.size() * 4) | 288 if (rect_history_for_layers_.capacity() > rect_history_for_layers_.size() * 4) |
| 286 SortedRectMapForLayers(rect_history_for_layers_) | 289 SortedRectMapForLayers(rect_history_for_layers_) |
| 287 .swap(rect_history_for_layers_); | 290 .swap(rect_history_for_layers_); |
| 288 if (rect_history_for_surfaces_.capacity() > | 291 if (rect_history_for_surfaces_.capacity() > |
| 289 rect_history_for_surfaces_.size() * 4) | 292 rect_history_for_surfaces_.size() * 4) |
| 290 SortedRectMapForSurfaces(rect_history_for_surfaces_) | 293 SortedRectMapForSurfaces(rect_history_for_surfaces_) |
| 291 .swap(rect_history_for_surfaces_); | 294 .swap(rect_history_for_surfaces_); |
| 292 | 295 |
| 293 return damage_rect; | 296 return damage; |
| 297 } | |
| 298 | |
| 299 void DamageTracker::ExpandDamageInsideRectWithFilters( | |
| 300 DamageAccumulator* damage, | |
| 301 const gfx::Rect& pre_filter_rect, | |
| 302 const FilterOperations& filters) { | |
| 303 gfx::Rect damage_rect; | |
| 304 bool is_valid_rect = damage->GetAsRect(&damage_rect); | |
| 305 // If the input isn't a valid rect, then there is no point in trying to make | |
| 306 // it bigger. | |
| 307 if (!is_valid_rect) | |
| 308 return; | |
| 309 | |
| 310 // Compute the pixels in the background of the surface that could be affected | |
| 311 // by the damage in the content below. | |
| 312 gfx::Rect expanded_damage_rect = filters.MapRect(damage_rect, SkMatrix::I()); | |
| 313 | |
| 314 // Restrict it to the rectangle in which the background filter is shown. | |
| 315 expanded_damage_rect.Intersect(pre_filter_rect); | |
| 316 | |
| 317 damage->Union(expanded_damage_rect); | |
| 294 } | 318 } |
| 295 | 319 |
| 296 void DamageTracker::ExtendDamageForLayer(LayerImpl* layer, | 320 void DamageTracker::ExtendDamageForLayer(LayerImpl* layer, |
| 297 gfx::Rect* target_damage_rect) { | 321 DamageAccumulator* target_damage) { |
| 298 // There are two ways that a layer can damage a region of the target surface: | 322 // There are two ways that a layer can damage a region of the target surface: |
| 299 // 1. Property change (e.g. opacity, position, transforms): | 323 // 1. Property change (e.g. opacity, position, transforms): |
| 300 // - the entire region of the layer itself damages the surface. | 324 // - the entire region of the layer itself damages the surface. |
| 301 // - the old layer region also damages the surface, because this region | 325 // - the old layer region also damages the surface, because this region |
| 302 // is now exposed. | 326 // is now exposed. |
| 303 // - note that in many cases the old and new layer rects may overlap, | 327 // - note that in many cases the old and new layer rects may overlap, |
| 304 // which is fine. | 328 // which is fine. |
| 305 // | 329 // |
| 306 // 2. Repaint/update: If a region of the layer that was repainted/updated, | 330 // 2. Repaint/update: If a region of the layer that was repainted/updated, |
| 307 // that region damages the surface. | 331 // that region damages the surface. |
| 308 // | 332 // |
| 309 // Property changes take priority over update rects. | 333 // Property changes take priority over update rects. |
| 310 // | 334 // |
| 311 // This method is called when we want to consider how a layer contributes to | 335 // This method is called when we want to consider how a layer contributes to |
| 312 // its target RenderSurface, even if that layer owns the target RenderSurface | 336 // its target RenderSurface, even if that layer owns the target RenderSurface |
| 313 // itself. To consider how a layer's target surface contributes to the | 337 // itself. To consider how a layer's target surface contributes to the |
| 314 // ancestor surface, ExtendDamageForRenderSurface() must be called instead. | 338 // ancestor surface, ExtendDamageForRenderSurface() must be called instead. |
| 315 | 339 |
| 316 bool layer_is_new = false; | 340 bool layer_is_new = false; |
| 317 LayerRectMapData& data = RectDataForLayer(layer->id(), &layer_is_new); | 341 LayerRectMapData& data = RectDataForLayer(layer->id(), &layer_is_new); |
| 318 gfx::Rect old_rect_in_target_space = data.rect_; | 342 gfx::Rect old_rect_in_target_space = data.rect_; |
| 319 | 343 |
| 320 gfx::Rect rect_in_target_space = layer->GetEnclosingRectInTargetSpace(); | 344 gfx::Rect rect_in_target_space = layer->GetEnclosingRectInTargetSpace(); |
| 321 data.Update(rect_in_target_space, mailboxId_); | 345 data.Update(rect_in_target_space, mailboxId_); |
| 322 | 346 |
| 323 if (layer_is_new || layer->LayerPropertyChanged()) { | 347 if (layer_is_new || layer->LayerPropertyChanged()) { |
| 324 // If a layer is new or has changed, then its entire layer rect affects the | 348 // If a layer is new or has changed, then its entire layer rect affects the |
| 325 // target surface. | 349 // target surface. |
| 326 target_damage_rect->Union(rect_in_target_space); | 350 target_damage->Union(rect_in_target_space); |
| 327 | 351 |
| 328 // The layer's old region is now exposed on the target surface, too. | 352 // The layer's old region is now exposed on the target surface, too. |
| 329 // Note old_rect_in_target_space is already in target space. | 353 // Note old_rect_in_target_space is already in target space. |
| 330 target_damage_rect->Union(old_rect_in_target_space); | 354 target_damage->Union(old_rect_in_target_space); |
| 331 return; | 355 return; |
| 332 } | 356 } |
| 333 | 357 |
| 334 // If the layer properties haven't changed, then the the target surface is | 358 // If the layer properties haven't changed, then the the target surface is |
| 335 // only affected by the layer's damaged area, which could be empty. | 359 // only affected by the layer's damaged area, which could be empty. |
| 336 gfx::Rect damage_rect = | 360 gfx::Rect damage_rect = |
| 337 gfx::UnionRects(layer->update_rect(), layer->damage_rect()); | 361 gfx::UnionRects(layer->update_rect(), layer->damage_rect()); |
| 338 damage_rect.Intersect(gfx::Rect(layer->bounds())); | 362 damage_rect.Intersect(gfx::Rect(layer->bounds())); |
| 339 if (!damage_rect.IsEmpty()) { | 363 if (!damage_rect.IsEmpty()) { |
| 340 gfx::Rect damage_rect_in_target_space = | 364 gfx::Rect damage_rect_in_target_space = |
| 341 MathUtil::MapEnclosingClippedRect(layer->DrawTransform(), damage_rect); | 365 MathUtil::MapEnclosingClippedRect(layer->DrawTransform(), damage_rect); |
| 342 target_damage_rect->Union(damage_rect_in_target_space); | 366 target_damage->Union(damage_rect_in_target_space); |
| 343 } | 367 } |
| 344 } | 368 } |
| 345 | 369 |
| 346 void DamageTracker::ExtendDamageForRenderSurface( | 370 void DamageTracker::ExtendDamageForRenderSurface( |
| 347 RenderSurfaceImpl* render_surface, | 371 RenderSurfaceImpl* render_surface, |
| 348 gfx::Rect* target_damage_rect) { | 372 DamageAccumulator* target_damage) { |
| 349 // There are two ways a "descendant surface" can damage regions of the "target | 373 // There are two ways a "descendant surface" can damage regions of the "target |
| 350 // surface": | 374 // surface": |
| 351 // 1. Property change: | 375 // 1. Property change: |
| 352 // - a surface's geometry can change because of | 376 // - a surface's geometry can change because of |
| 353 // - changes to descendants (i.e. the subtree) that affect the | 377 // - changes to descendants (i.e. the subtree) that affect the |
| 354 // surface's content rect | 378 // surface's content rect |
| 355 // - changes to ancestor layers that propagate their property | 379 // - changes to ancestor layers that propagate their property |
| 356 // changes to their entire subtree. | 380 // changes to their entire subtree. |
| 357 // - just like layers, both the old surface rect and new surface rect | 381 // - just like layers, both the old surface rect and new surface rect |
| 358 // will damage the target surface in this case. | 382 // will damage the target surface in this case. |
| 359 // | 383 // |
| 360 // 2. Damage rect: This surface may have been damaged by its own layer_list | 384 // 2. Damage rect: This surface may have been damaged by its own layer_list |
| 361 // as well, and that damage should propagate to the target surface. | 385 // as well, and that damage should propagate to the target surface. |
| 362 // | 386 // |
| 363 | 387 |
| 364 bool surface_is_new = false; | 388 bool surface_is_new = false; |
| 365 SurfaceRectMapData& data = | 389 SurfaceRectMapData& data = |
| 366 RectDataForSurface(render_surface->id(), &surface_is_new); | 390 RectDataForSurface(render_surface->id(), &surface_is_new); |
| 367 gfx::Rect old_surface_rect = data.rect_; | 391 gfx::Rect old_surface_rect = data.rect_; |
| 368 | 392 |
| 369 gfx::Rect surface_rect_in_target_space = | 393 gfx::Rect surface_rect_in_target_space = |
| 370 gfx::ToEnclosingRect(render_surface->DrawableContentRect()); | 394 gfx::ToEnclosingRect(render_surface->DrawableContentRect()); |
| 371 data.Update(surface_rect_in_target_space, mailboxId_); | 395 data.Update(surface_rect_in_target_space, mailboxId_); |
| 372 | 396 |
| 373 if (surface_is_new || render_surface->SurfacePropertyChanged()) { | 397 if (surface_is_new || render_surface->SurfacePropertyChanged()) { |
| 374 // The entire surface contributes damage. | 398 // The entire surface contributes damage. |
| 375 target_damage_rect->Union(surface_rect_in_target_space); | 399 target_damage->Union(surface_rect_in_target_space); |
| 376 | 400 |
| 377 // The surface's old region is now exposed on the target surface, too. | 401 // The surface's old region is now exposed on the target surface, too. |
| 378 target_damage_rect->Union(old_surface_rect); | 402 target_damage->Union(old_surface_rect); |
| 379 } else { | 403 } else { |
| 380 // Only the surface's damage_rect will damage the target surface. | 404 // Only the surface's damage_rect will damage the target surface. |
| 381 gfx::Rect damage_rect_in_local_space = | 405 if (render_surface->damage_tracker()->ShouldDamageEverything()) { |
| 382 render_surface->damage_tracker()->current_damage_rect(); | 406 target_damage->SetInvalid(); |
|
enne (OOO)
2017/01/13 22:21:38
Should you use the render surface content rect as
vmpstr
2017/01/19 23:08:27
Done.
| |
| 407 } else { | |
| 408 gfx::Rect damage_rect_in_local_space = | |
| 409 render_surface->damage_tracker()->CurrentDamageRect(); | |
| 383 | 410 |
| 384 // If there was damage, transform it to target space, and possibly | 411 // If there was damage, transform it to target space, and possibly |
| 385 // contribute its reflection if needed. | 412 // contribute its reflection if needed. |
| 386 if (!damage_rect_in_local_space.IsEmpty()) { | 413 if (!damage_rect_in_local_space.IsEmpty()) { |
| 387 const gfx::Transform& draw_transform = render_surface->draw_transform(); | 414 const gfx::Transform& draw_transform = render_surface->draw_transform(); |
| 388 gfx::Rect damage_rect_in_target_space = MathUtil::MapEnclosingClippedRect( | 415 gfx::Rect damage_rect_in_target_space = |
| 389 draw_transform, damage_rect_in_local_space); | 416 MathUtil::MapEnclosingClippedRect(draw_transform, |
| 390 target_damage_rect->Union(damage_rect_in_target_space); | 417 damage_rect_in_local_space); |
| 418 target_damage->Union(damage_rect_in_target_space); | |
| 419 } | |
| 391 } | 420 } |
| 392 } | 421 } |
| 393 | 422 |
| 394 // If the layer has a background filter, this may cause pixels in our surface | 423 // If the layer has a background filter, this may cause pixels in our surface |
| 395 // to be expanded, so we will need to expand any damage at or below this | 424 // to be expanded, so we will need to expand any damage at or below this |
| 396 // layer. We expand the damage from this layer too, as we need to readback | 425 // layer. We expand the damage from this layer too, as we need to readback |
| 397 // those pixels from the surface with only the contents of layers below this | 426 // those pixels from the surface with only the contents of layers below this |
| 398 // one in them. This means we need to redraw any pixels in the surface being | 427 // one in them. This means we need to redraw any pixels in the surface being |
| 399 // used for the blur in this layer this frame. | 428 // used for the blur in this layer this frame. |
| 400 const FilterOperations& background_filters = | 429 const FilterOperations& background_filters = |
| 401 render_surface->BackgroundFilters(); | 430 render_surface->BackgroundFilters(); |
| 402 if (background_filters.HasFilterThatMovesPixels()) { | 431 if (background_filters.HasFilterThatMovesPixels()) { |
| 403 ExpandDamageRectInsideRectWithFilters( | 432 ExpandDamageInsideRectWithFilters( |
| 404 target_damage_rect, surface_rect_in_target_space, background_filters); | 433 target_damage, surface_rect_in_target_space, background_filters); |
| 405 } | 434 } |
| 406 } | 435 } |
| 407 | 436 |
| 437 bool DamageTracker::DamageAccumulator::GetAsRect(gfx::Rect* rect) { | |
| 438 if (!is_valid_rect_) { | |
| 439 *rect = gfx::Rect(); | |
|
danakj
2017/01/13 23:17:58
think not needed? dont use the rect if return is f
vmpstr
2017/01/19 23:08:27
Done.
| |
| 440 return false; | |
| 441 } | |
| 442 | |
| 443 double width = right_ - static_cast<double>(x_); | |
|
danakj
2017/01/13 23:17:58
does not base::CheckedNumeric do this stuff and yo
vmpstr
2017/01/19 23:08:27
Done.
| |
| 444 if (width > static_cast<double>(std::numeric_limits<int>::max())) { | |
|
danakj
2017/01/13 23:17:58
if not, can you store the intmax as a double in a
vmpstr
2017/01/19 23:08:27
Removed this.
| |
| 445 *rect = gfx::Rect(); | |
| 446 is_valid_rect_ = false; | |
| 447 return false; | |
| 448 } | |
| 449 double height = bottom_ - static_cast<double>(bottom_); | |
| 450 if (height > static_cast<double>(std::numeric_limits<int>::max())) { | |
| 451 *rect = gfx::Rect(); | |
| 452 is_valid_rect_ = false; | |
| 453 return false; | |
| 454 } | |
| 455 | |
| 456 rect->set_x(x_); | |
| 457 rect->set_y(y_); | |
| 458 rect->set_width(right_ - x_); | |
| 459 rect->set_height(bottom_ - y_); | |
| 460 return true; | |
| 461 } | |
| 462 | |
| 408 } // namespace cc | 463 } // namespace cc |
| OLD | NEW |