| 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 135 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 146 damage_rect_for_this_update.Union(damage_from_leftover_rects); | 146 damage_rect_for_this_update.Union(damage_from_leftover_rects); |
| 147 | 147 |
| 148 ExpandRectWithFilters(&damage_rect_for_this_update, filters); | 148 ExpandRectWithFilters(&damage_rect_for_this_update, filters); |
| 149 } | 149 } |
| 150 | 150 |
| 151 // Damage accumulates until we are notified that we actually did draw on that | 151 // Damage accumulates until we are notified that we actually did draw on that |
| 152 // frame. | 152 // frame. |
| 153 current_damage_rect_.Union(damage_rect_for_this_update); | 153 current_damage_rect_.Union(damage_rect_for_this_update); |
| 154 } | 154 } |
| 155 | 155 |
| 156 DamageTracker::RectMapData& DamageTracker::RectDataForLayer( | 156 DamageTracker::LayerRectMapData& DamageTracker::RectDataForLayer( |
| 157 int layer_id, | 157 int layer_id, |
| 158 bool* layer_is_new) { | 158 bool* layer_is_new) { |
| 159 LayerRectMapData data(layer_id); |
| 159 | 160 |
| 160 RectMapData data(layer_id); | 161 SortedRectMapForLayers::iterator it = std::lower_bound( |
| 162 rect_history_for_layers_.begin(), rect_history_for_layers_.end(), data); |
| 161 | 163 |
| 162 SortedRectMap::iterator it = std::lower_bound(rect_history_.begin(), | 164 if (it == rect_history_for_layers_.end() || it->layer_id_ != layer_id) { |
| 163 rect_history_.end(), data); | |
| 164 | |
| 165 if (it == rect_history_.end() || it->layer_id_ != layer_id) { | |
| 166 *layer_is_new = true; | 165 *layer_is_new = true; |
| 167 it = rect_history_.insert(it, data); | 166 it = rect_history_for_layers_.insert(it, data); |
| 168 } | 167 } |
| 169 | 168 |
| 170 return *it; | 169 return *it; |
| 170 } |
| 171 |
| 172 DamageTracker::SurfaceRectMapData& DamageTracker::RectDataForSurface( |
| 173 int surface_id, |
| 174 bool* surface_is_new) { |
| 175 SurfaceRectMapData data(surface_id); |
| 176 |
| 177 SortedRectMapForSurfaces::iterator it = |
| 178 std::lower_bound(rect_history_for_surfaces_.begin(), |
| 179 rect_history_for_surfaces_.end(), data); |
| 180 |
| 181 if (it == rect_history_for_surfaces_.end() || it->surface_id_ != surface_id) { |
| 182 *surface_is_new = true; |
| 183 it = rect_history_for_surfaces_.insert(it, data); |
| 184 } |
| 185 |
| 186 return *it; |
| 171 } | 187 } |
| 172 | 188 |
| 173 gfx::Rect DamageTracker::TrackDamageFromActiveLayers( | 189 gfx::Rect DamageTracker::TrackDamageFromActiveLayers( |
| 174 const LayerImplList& layer_list, | 190 const LayerImplList& layer_list, |
| 175 const RenderSurfaceImpl* target_surface) { | 191 const RenderSurfaceImpl* target_surface) { |
| 176 gfx::Rect damage_rect; | 192 gfx::Rect damage_rect; |
| 177 | 193 |
| 178 for (size_t layer_index = 0; layer_index < layer_list.size(); ++layer_index) { | 194 for (size_t layer_index = 0; layer_index < layer_list.size(); ++layer_index) { |
| 179 // Visit layers in back-to-front order. | 195 // Visit layers in back-to-front order. |
| 180 LayerImpl* layer = layer_list[layer_index]; | 196 LayerImpl* layer = layer_list[layer_index]; |
| (...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 215 void DamageTracker::PrepareRectHistoryForUpdate() { | 231 void DamageTracker::PrepareRectHistoryForUpdate() { |
| 216 mailboxId_++; | 232 mailboxId_++; |
| 217 } | 233 } |
| 218 | 234 |
| 219 gfx::Rect DamageTracker::TrackDamageFromLeftoverRects() { | 235 gfx::Rect DamageTracker::TrackDamageFromLeftoverRects() { |
| 220 // After computing damage for all active layers, any leftover items in the | 236 // After computing damage for all active layers, any leftover items in the |
| 221 // current rect history correspond to layers/surfaces that no longer exist. | 237 // current rect history correspond to layers/surfaces that no longer exist. |
| 222 // So, these regions are now exposed on the target surface. | 238 // So, these regions are now exposed on the target surface. |
| 223 | 239 |
| 224 gfx::Rect damage_rect; | 240 gfx::Rect damage_rect; |
| 225 SortedRectMap::iterator cur_pos = rect_history_.begin(); | 241 SortedRectMapForLayers::iterator layer_cur_pos = |
| 226 SortedRectMap::iterator copy_pos = cur_pos; | 242 rect_history_for_layers_.begin(); |
| 243 SortedRectMapForLayers::iterator layer_copy_pos = layer_cur_pos; |
| 244 SortedRectMapForSurfaces::iterator surface_cur_pos = |
| 245 rect_history_for_surfaces_.begin(); |
| 246 SortedRectMapForSurfaces::iterator surface_copy_pos = surface_cur_pos; |
| 227 | 247 |
| 228 // Loop below basically implements std::remove_if loop with and extra | 248 // Loop below basically implements std::remove_if loop with and extra |
| 229 // processing (adding deleted rect to damage_rect) for deleted items. | 249 // processing (adding deleted rect to damage_rect) for deleted items. |
| 230 // cur_pos iterator runs through all elements of the vector, but copy_pos | 250 // cur_pos iterator runs through all elements of the vector, but copy_pos |
| 231 // always points to the element after the last not deleted element. If new | 251 // always points to the element after the last not deleted element. If new |
| 232 // not deleted element found then it is copied to the *copy_pos and copy_pos | 252 // not deleted element found then it is copied to the *copy_pos and copy_pos |
| 233 // moved to the next position. | 253 // moved to the next position. |
| 234 // If there are no deleted elements then copy_pos iterator is in sync with | 254 // If there are no deleted elements then copy_pos iterator is in sync with |
| 235 // cur_pos and no copy happens. | 255 // cur_pos and no copy happens. |
| 236 while (cur_pos < rect_history_.end()) { | 256 while (layer_cur_pos < rect_history_for_layers_.end()) { |
| 237 if (cur_pos->mailboxId_ == mailboxId_) { | 257 if (layer_cur_pos->mailboxId_ == mailboxId_) { |
| 238 if (cur_pos != copy_pos) | 258 if (layer_cur_pos != layer_copy_pos) |
| 239 *copy_pos = *cur_pos; | 259 *layer_copy_pos = *layer_cur_pos; |
| 240 | 260 |
| 241 ++copy_pos; | 261 ++layer_copy_pos; |
| 242 } else { | 262 } else { |
| 243 damage_rect.Union(cur_pos->rect_); | 263 damage_rect.Union(layer_cur_pos->rect_); |
| 244 } | 264 } |
| 245 | 265 |
| 246 ++cur_pos; | 266 ++layer_cur_pos; |
| 247 } | 267 } |
| 248 | 268 |
| 249 if (copy_pos != rect_history_.end()) | 269 while (surface_cur_pos < rect_history_for_surfaces_.end()) { |
| 250 rect_history_.erase(copy_pos, rect_history_.end()); | 270 if (surface_cur_pos->mailboxId_ == mailboxId_) { |
| 271 if (surface_cur_pos != surface_copy_pos) |
| 272 *surface_copy_pos = *surface_cur_pos; |
| 273 |
| 274 ++surface_copy_pos; |
| 275 } else { |
| 276 damage_rect.Union(surface_cur_pos->rect_); |
| 277 } |
| 278 |
| 279 ++surface_cur_pos; |
| 280 } |
| 281 |
| 282 if (layer_copy_pos != rect_history_for_layers_.end()) |
| 283 rect_history_for_layers_.erase(layer_copy_pos, |
| 284 rect_history_for_layers_.end()); |
| 285 if (surface_copy_pos != rect_history_for_surfaces_.end()) |
| 286 rect_history_for_surfaces_.erase(surface_copy_pos, |
| 287 rect_history_for_surfaces_.end()); |
| 251 | 288 |
| 252 // If the vector has excessive storage, shrink it | 289 // If the vector has excessive storage, shrink it |
| 253 if (rect_history_.capacity() > rect_history_.size() * 4) | 290 if (rect_history_for_layers_.capacity() > rect_history_for_layers_.size() * 4) |
| 254 SortedRectMap(rect_history_).swap(rect_history_); | 291 SortedRectMapForLayers(rect_history_for_layers_) |
| 292 .swap(rect_history_for_layers_); |
| 293 if (rect_history_for_surfaces_.capacity() > |
| 294 rect_history_for_surfaces_.size() * 4) |
| 295 SortedRectMapForSurfaces(rect_history_for_surfaces_) |
| 296 .swap(rect_history_for_surfaces_); |
| 255 | 297 |
| 256 return damage_rect; | 298 return damage_rect; |
| 257 } | 299 } |
| 258 | 300 |
| 259 void DamageTracker::ExtendDamageForLayer(LayerImpl* layer, | 301 void DamageTracker::ExtendDamageForLayer(LayerImpl* layer, |
| 260 gfx::Rect* target_damage_rect) { | 302 gfx::Rect* target_damage_rect) { |
| 261 // There are two ways that a layer can damage a region of the target surface: | 303 // There are two ways that a layer can damage a region of the target surface: |
| 262 // 1. Property change (e.g. opacity, position, transforms): | 304 // 1. Property change (e.g. opacity, position, transforms): |
| 263 // - the entire region of the layer itself damages the surface. | 305 // - the entire region of the layer itself damages the surface. |
| 264 // - the old layer region also damages the surface, because this region | 306 // - the old layer region also damages the surface, because this region |
| 265 // is now exposed. | 307 // is now exposed. |
| 266 // - note that in many cases the old and new layer rects may overlap, | 308 // - note that in many cases the old and new layer rects may overlap, |
| 267 // which is fine. | 309 // which is fine. |
| 268 // | 310 // |
| 269 // 2. Repaint/update: If a region of the layer that was repainted/updated, | 311 // 2. Repaint/update: If a region of the layer that was repainted/updated, |
| 270 // that region damages the surface. | 312 // that region damages the surface. |
| 271 // | 313 // |
| 272 // Property changes take priority over update rects. | 314 // Property changes take priority over update rects. |
| 273 // | 315 // |
| 274 // This method is called when we want to consider how a layer contributes to | 316 // This method is called when we want to consider how a layer contributes to |
| 275 // its target RenderSurface, even if that layer owns the target RenderSurface | 317 // its target RenderSurface, even if that layer owns the target RenderSurface |
| 276 // itself. To consider how a layer's target surface contributes to the | 318 // itself. To consider how a layer's target surface contributes to the |
| 277 // ancestor surface, ExtendDamageForRenderSurface() must be called instead. | 319 // ancestor surface, ExtendDamageForRenderSurface() must be called instead. |
| 278 | 320 |
| 279 bool layer_is_new = false; | 321 bool layer_is_new = false; |
| 280 RectMapData& data = RectDataForLayer(layer->id(), &layer_is_new); | 322 LayerRectMapData& data = RectDataForLayer(layer->id(), &layer_is_new); |
| 281 gfx::Rect old_rect_in_target_space = data.rect_; | 323 gfx::Rect old_rect_in_target_space = data.rect_; |
| 282 | 324 |
| 283 gfx::Rect rect_in_target_space = layer->GetEnclosingRectInTargetSpace(); | 325 gfx::Rect rect_in_target_space = layer->GetEnclosingRectInTargetSpace(); |
| 284 data.Update(rect_in_target_space, mailboxId_); | 326 data.Update(rect_in_target_space, mailboxId_); |
| 285 | 327 |
| 286 if (layer_is_new || layer->LayerPropertyChanged()) { | 328 if (layer_is_new || layer->LayerPropertyChanged()) { |
| 287 // If a layer is new or has changed, then its entire layer rect affects the | 329 // If a layer is new or has changed, then its entire layer rect affects the |
| 288 // target surface. | 330 // target surface. |
| 289 target_damage_rect->Union(rect_in_target_space); | 331 target_damage_rect->Union(rect_in_target_space); |
| 290 | 332 |
| (...skipping 29 matching lines...) Expand all Loading... |
| 320 // - just like layers, both the old surface rect and new surface rect | 362 // - just like layers, both the old surface rect and new surface rect |
| 321 // will damage the target surface in this case. | 363 // will damage the target surface in this case. |
| 322 // | 364 // |
| 323 // 2. Damage rect: This surface may have been damaged by its own layer_list | 365 // 2. Damage rect: This surface may have been damaged by its own layer_list |
| 324 // as well, and that damage should propagate to the target surface. | 366 // as well, and that damage should propagate to the target surface. |
| 325 // | 367 // |
| 326 | 368 |
| 327 RenderSurfaceImpl* render_surface = layer->render_surface(); | 369 RenderSurfaceImpl* render_surface = layer->render_surface(); |
| 328 | 370 |
| 329 bool surface_is_new = false; | 371 bool surface_is_new = false; |
| 330 RectMapData& data = RectDataForLayer(layer->id(), &surface_is_new); | 372 SurfaceRectMapData& data = RectDataForSurface(layer->id(), &surface_is_new); |
| 331 gfx::Rect old_surface_rect = data.rect_; | 373 gfx::Rect old_surface_rect = data.rect_; |
| 332 | 374 |
| 333 // The drawableContextRect() already includes the replica if it exists. | 375 // The drawableContextRect() already includes the replica if it exists. |
| 334 gfx::Rect surface_rect_in_target_space = | 376 gfx::Rect surface_rect_in_target_space = |
| 335 gfx::ToEnclosingRect(render_surface->DrawableContentRect()); | 377 gfx::ToEnclosingRect(render_surface->DrawableContentRect()); |
| 336 data.Update(surface_rect_in_target_space, mailboxId_); | 378 data.Update(surface_rect_in_target_space, mailboxId_); |
| 337 | 379 |
| 338 if (surface_is_new || render_surface->SurfacePropertyChanged()) { | 380 if (surface_is_new || render_surface->SurfacePropertyChanged()) { |
| 339 // The entire surface contributes damage. | 381 // The entire surface contributes damage. |
| 340 target_damage_rect->Union(surface_rect_in_target_space); | 382 target_damage_rect->Union(surface_rect_in_target_space); |
| (...skipping 21 matching lines...) Expand all Loading... |
| 362 } | 404 } |
| 363 } | 405 } |
| 364 } | 406 } |
| 365 | 407 |
| 366 // If there was damage on the replica's mask, then the target surface receives | 408 // If there was damage on the replica's mask, then the target surface receives |
| 367 // that damage as well. | 409 // that damage as well. |
| 368 if (layer->replica_layer() && layer->replica_layer()->mask_layer()) { | 410 if (layer->replica_layer() && layer->replica_layer()->mask_layer()) { |
| 369 LayerImpl* replica_mask_layer = layer->replica_layer()->mask_layer(); | 411 LayerImpl* replica_mask_layer = layer->replica_layer()->mask_layer(); |
| 370 | 412 |
| 371 bool replica_is_new = false; | 413 bool replica_is_new = false; |
| 372 RectMapData& data = | 414 LayerRectMapData& data = |
| 373 RectDataForLayer(replica_mask_layer->id(), &replica_is_new); | 415 RectDataForLayer(replica_mask_layer->id(), &replica_is_new); |
| 374 | 416 |
| 375 const gfx::Transform& replica_draw_transform = | 417 const gfx::Transform& replica_draw_transform = |
| 376 render_surface->replica_draw_transform(); | 418 render_surface->replica_draw_transform(); |
| 377 gfx::Rect replica_mask_layer_rect = MathUtil::MapEnclosingClippedRect( | 419 gfx::Rect replica_mask_layer_rect = MathUtil::MapEnclosingClippedRect( |
| 378 replica_draw_transform, gfx::Rect(replica_mask_layer->bounds())); | 420 replica_draw_transform, gfx::Rect(replica_mask_layer->bounds())); |
| 379 data.Update(replica_mask_layer_rect, mailboxId_); | 421 data.Update(replica_mask_layer_rect, mailboxId_); |
| 380 | 422 |
| 381 // In the current implementation, a change in the replica mask damages the | 423 // In the current implementation, a change in the replica mask damages the |
| 382 // entire replica region. | 424 // entire replica region. |
| (...skipping 10 matching lines...) Expand all Loading... |
| 393 // one in them. This means we need to redraw any pixels in the surface being | 435 // one in them. This means we need to redraw any pixels in the surface being |
| 394 // used for the blur in this layer this frame. | 436 // used for the blur in this layer this frame. |
| 395 if (layer->background_filters().HasFilterThatMovesPixels()) { | 437 if (layer->background_filters().HasFilterThatMovesPixels()) { |
| 396 ExpandDamageRectInsideRectWithFilters(target_damage_rect, | 438 ExpandDamageRectInsideRectWithFilters(target_damage_rect, |
| 397 surface_rect_in_target_space, | 439 surface_rect_in_target_space, |
| 398 layer->background_filters()); | 440 layer->background_filters()); |
| 399 } | 441 } |
| 400 } | 442 } |
| 401 | 443 |
| 402 } // namespace cc | 444 } // namespace cc |
| OLD | NEW |