12a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Copyright 2011 The Chromium Authors. All rights reserved. 22a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be 32a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// found in the LICENSE file. 42a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 52a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "cc/trees/damage_tracker.h" 62a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 7c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include <algorithm> 8c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 92a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "cc/base/math_util.h" 10c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "cc/layers/heads_up_display_layer_impl.h" 112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "cc/layers/layer_impl.h" 122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "cc/layers/render_surface_impl.h" 13eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#include "cc/output/filter_operations.h" 142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "cc/trees/layer_tree_host_common.h" 15c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "cc/trees/layer_tree_impl.h" 16c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch#include "ui/gfx/geometry/rect_conversions.h" 172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)namespace cc { 192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)scoped_ptr<DamageTracker> DamageTracker::Create() { 212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return make_scoped_ptr(new DamageTracker()); 222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)DamageTracker::DamageTracker() 25f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) : mailboxId_(0) {} 262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)DamageTracker::~DamageTracker() {} 282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 29c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdochstatic inline void ExpandRectWithFilters(gfx::Rect* rect, 30c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch const FilterOperations& filters) { 312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) int top, right, bottom, left; 32eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch filters.GetOutsets(&top, &right, &bottom, &left); 332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) rect->Inset(-left, -top, -right, -bottom); 342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)static inline void ExpandDamageRectInsideRectWithFilters( 37c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch gfx::Rect* damage_rect, 38c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch const gfx::Rect& pre_filter_rect, 39eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch const FilterOperations& filters) { 40c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch gfx::Rect expanded_damage_rect = *damage_rect; 412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ExpandRectWithFilters(&expanded_damage_rect, filters); 42c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch gfx::Rect filter_rect = pre_filter_rect; 432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ExpandRectWithFilters(&filter_rect, filters); 442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) expanded_damage_rect.Intersect(filter_rect); 462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) damage_rect->Union(expanded_damage_rect); 472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void DamageTracker::UpdateDamageTrackingState( 50c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) const LayerImplList& layer_list, 512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) int target_surface_layer_id, 522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) bool target_surface_property_changed_only_from_descendant, 535d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) const gfx::Rect& target_surface_content_rect, 542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) LayerImpl* target_surface_mask_layer, 5568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) const FilterOperations& filters) { 562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // 572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // This function computes the "damage rect" of a target surface, and updates 582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // the state that is used to correctly track damage across frames. The damage 592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // rect is the region of the surface that may have changed and needs to be 602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // redrawn. This can be used to scissor what is actually drawn, to save GPU 612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // computation and bandwidth. 622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // 632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // The surface's damage rect is computed as the union of all possible changes 642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // that have happened to the surface since the last frame was drawn. This 652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // includes: 662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // - any changes for existing layers/surfaces that contribute to the target 672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // surface 682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // - layers/surfaces that existed in the previous frame, but no longer exist 692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // 702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // The basic algorithm for computing the damage region is as follows: 712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // 722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // 1. compute damage caused by changes in active/new layers 732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // for each layer in the layer_list: 742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // if the layer is actually a render_surface: 752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // add the surface's damage to our target surface. 762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // else 772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // add the layer's damage to the target surface. 782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // 792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // 2. compute damage caused by the target surface's mask, if it exists. 802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // 812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // 3. compute damage caused by old layers/surfaces that no longer exist 822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // for each leftover layer: 832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // add the old layer/surface bounds to the target surface damage. 842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // 852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // 4. combine all partial damage rects to get the full damage rect. 862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // 872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Additional important points: 882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // 892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // - This algorithm is implicitly recursive; it assumes that descendant 902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // surfaces have already computed their damage. 912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // 922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // - Changes to layers/surfaces indicate "damage" to the target surface; If a 932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // layer is not changed, it does NOT mean that the layer can skip drawing. 942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // All layers that overlap the damaged region still need to be drawn. For 952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // example, if a layer changed its opacity, then layers underneath must be 962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // re-drawn as well, even if they did not change. 972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // 982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // - If a layer/surface property changed, the old bounds and new bounds may 992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // overlap... i.e. some of the exposed region may not actually be exposing 1002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // anything. But this does not artificially inflate the damage rect. If the 1012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // layer changed, its entire old bounds would always need to be redrawn, 1022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // regardless of how much it overlaps with the layer's new bounds, which 1032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // also need to be entirely redrawn. 1042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // 1052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // - See comments in the rest of the code to see what exactly is considered a 1062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // "change" in a layer/surface. 1072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // 108f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // - To correctly manage exposed rects, SortedRectMap is maintained: 1092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // 110f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // 1. All existing rects from the previous frame are marked as 111f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // not updated. 112f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // 2. The map contains all the layer bounds that contributed to 1132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // the previous frame (even outside the previous damaged area). If a 1142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // layer changes or does not exist anymore, those regions are then 1152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // exposed and damage the target surface. As the algorithm progresses, 116f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // entries are updated in the map until only leftover layers 117f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // that no longer exist stay marked not updated. 1182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // 119f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // 3. After the damage rect is computed, the leftover not marked regions 120f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // in a map are used to compute are damaged by deleted layers and 121f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // erased from map. 1222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // 1232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 124f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) PrepareRectHistoryForUpdate(); 1252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // These functions cannot be bypassed with early-exits, even if we know what 1262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // the damage will be for this frame, because we need to update the damage 1272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // tracker state to correctly track the next frame. 128c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch gfx::Rect damage_from_active_layers = 1292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) TrackDamageFromActiveLayers(layer_list, target_surface_layer_id); 130c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch gfx::Rect damage_from_surface_mask = 1312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) TrackDamageFromSurfaceMask(target_surface_mask_layer); 132c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch gfx::Rect damage_from_leftover_rects = TrackDamageFromLeftoverRects(); 1332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 134c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch gfx::Rect damage_rect_for_this_update; 1352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 136c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (target_surface_property_changed_only_from_descendant) { 1372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) damage_rect_for_this_update = target_surface_content_rect; 1382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } else { 1392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // TODO(shawnsingh): can we clamp this damage to the surface's content rect? 1402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // (affects performance, but not correctness) 1412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) damage_rect_for_this_update = damage_from_active_layers; 1422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) damage_rect_for_this_update.Union(damage_from_surface_mask); 1432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) damage_rect_for_this_update.Union(damage_from_leftover_rects); 1442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 14568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) if (filters.HasReferenceFilter()) { 1462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // TODO(senorblanco): Once SkImageFilter reports its outsets, use 1472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // those here to limit damage. 1482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) damage_rect_for_this_update = target_surface_content_rect; 14968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) } else if (filters.HasFilterThatMovesPixels()) { 15068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) ExpandRectWithFilters(&damage_rect_for_this_update, filters); 1512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 1522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 1532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Damage accumulates until we are notified that we actually did draw on that 1552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // frame. 1562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) current_damage_rect_.Union(damage_rect_for_this_update); 1572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 1582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 159f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)DamageTracker::RectMapData& DamageTracker::RectDataForLayer( 160f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) int layer_id, 161f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) bool* layer_is_new) { 1622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 163f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) RectMapData data(layer_id); 164f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 165f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) SortedRectMap::iterator it = std::lower_bound(rect_history_.begin(), 166f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) rect_history_.end(), data); 167f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 168f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) if (it == rect_history_.end() || it->layer_id_ != layer_id) { 169f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) *layer_is_new = true; 170f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) it = rect_history_.insert(it, data); 171f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) } 1722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 173f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) return *it; 1742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 1752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 176c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdochgfx::Rect DamageTracker::TrackDamageFromActiveLayers( 177c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) const LayerImplList& layer_list, 1782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) int target_surface_layer_id) { 179c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch gfx::Rect damage_rect; 1802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) for (size_t layer_index = 0; layer_index < layer_list.size(); ++layer_index) { 1822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Visit layers in back-to-front order. 1832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) LayerImpl* layer = layer_list[layer_index]; 1842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 185c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // We skip damage from the HUD layer because (a) the HUD layer damages the 186c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // whole frame and (b) we don't want HUD layer damage to be shown by the 187c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // HUD damage rect visualization. 188c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (layer == layer->layer_tree_impl()->hud_layer()) 189c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) continue; 1902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (LayerTreeHostCommon::RenderSurfaceContributesToTarget<LayerImpl>( 1912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) layer, target_surface_layer_id)) 1922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ExtendDamageForRenderSurface(layer, &damage_rect); 1932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) else 1942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ExtendDamageForLayer(layer, &damage_rect); 1952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 1962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return damage_rect; 1982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 1992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 200c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdochgfx::Rect DamageTracker::TrackDamageFromSurfaceMask( 2012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) LayerImpl* target_surface_mask_layer) { 202c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch gfx::Rect damage_rect; 2032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (!target_surface_mask_layer) 2052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return damage_rect; 2062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Currently, if there is any change to the mask, we choose to damage the 2082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // entire surface. This could potentially be optimized later, but it is not 2092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // expected to be a common case. 2102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (target_surface_mask_layer->LayerPropertyChanged() || 2112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) !target_surface_mask_layer->update_rect().IsEmpty()) { 212c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch damage_rect = gfx::Rect(target_surface_mask_layer->bounds()); 2132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 2142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return damage_rect; 2162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 2172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 218f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)void DamageTracker::PrepareRectHistoryForUpdate() { 219f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) mailboxId_++; 220f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)} 221f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 222c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdochgfx::Rect DamageTracker::TrackDamageFromLeftoverRects() { 2232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // After computing damage for all active layers, any leftover items in the 2242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // current rect history correspond to layers/surfaces that no longer exist. 2252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // So, these regions are now exposed on the target surface. 2262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 227c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch gfx::Rect damage_rect; 228f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) SortedRectMap::iterator cur_pos = rect_history_.begin(); 229f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) SortedRectMap::iterator copy_pos = cur_pos; 230f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 231f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // Loop below basically implements std::remove_if loop with and extra 232f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // processing (adding deleted rect to damage_rect) for deleted items. 233f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // cur_pos iterator runs through all elements of the vector, but copy_pos 234f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // always points to the element after the last not deleted element. If new 235f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // not deleted element found then it is copied to the *copy_pos and copy_pos 236f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // moved to the next position. 237f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // If there are no deleted elements then copy_pos iterator is in sync with 238f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // cur_pos and no copy happens. 239f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) while (cur_pos < rect_history_.end()) { 240f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) if (cur_pos->mailboxId_ == mailboxId_) { 241f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) if (cur_pos != copy_pos) 242f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) *copy_pos = *cur_pos; 243f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 244f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) ++copy_pos; 245f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) } else { 246f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) damage_rect.Union(cur_pos->rect_); 247f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) } 248f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 249f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) ++cur_pos; 250f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) } 2512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 252f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) if (copy_pos != rect_history_.end()) 253f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) rect_history_.erase(copy_pos, rect_history_.end()); 2542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 255f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // If the vector has excessive storage, shrink it 256f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) if (rect_history_.capacity() > rect_history_.size() * 4) 257f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) SortedRectMap(rect_history_).swap(rect_history_); 2582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return damage_rect; 2602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 2612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void DamageTracker::ExtendDamageForLayer(LayerImpl* layer, 263c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch gfx::Rect* target_damage_rect) { 2642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // There are two ways that a layer can damage a region of the target surface: 2652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // 1. Property change (e.g. opacity, position, transforms): 2662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // - the entire region of the layer itself damages the surface. 2672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // - the old layer region also damages the surface, because this region 2682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // is now exposed. 2692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // - note that in many cases the old and new layer rects may overlap, 2702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // which is fine. 2712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // 2722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // 2. Repaint/update: If a region of the layer that was repainted/updated, 2732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // that region damages the surface. 2742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // 2752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Property changes take priority over update rects. 2762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // 2772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // This method is called when we want to consider how a layer contributes to 2782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // its target RenderSurface, even if that layer owns the target RenderSurface 2792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // itself. To consider how a layer's target surface contributes to the 2802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // ancestor surface, ExtendDamageForRenderSurface() must be called instead. 2812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) bool layer_is_new = false; 283f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) RectMapData& data = RectDataForLayer(layer->id(), &layer_is_new); 284c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch gfx::Rect old_rect_in_target_space = data.rect_; 2852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 286c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch gfx::Rect rect_in_target_space = MathUtil::MapEnclosingClippedRect( 287c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch layer->draw_transform(), gfx::Rect(layer->content_bounds())); 288f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) data.Update(rect_in_target_space, mailboxId_); 2892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2905c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu gfx::RectF damage_rect = 2915c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu gfx::UnionRects(layer->update_rect(), layer->damage_rect()); 2925c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu 2934e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) if (layer_is_new || layer->LayerPropertyChanged()) { 2942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // If a layer is new or has changed, then its entire layer rect affects the 2952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // target surface. 2962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) target_damage_rect->Union(rect_in_target_space); 2972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // The layer's old region is now exposed on the target surface, too. 2992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Note old_rect_in_target_space is already in target space. 3002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) target_damage_rect->Union(old_rect_in_target_space); 3015c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu } else if (!damage_rect.IsEmpty()) { 3022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // If the layer properties haven't changed, then the the target surface is 3035c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu // only affected by the layer's damaged area, which could be empty. 3045c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu gfx::Rect damage_content_rect = layer->LayerRectToContentRect(damage_rect); 3055c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu gfx::Rect damage_rect_in_target_space = MathUtil::MapEnclosingClippedRect( 3065c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu layer->draw_transform(), damage_content_rect); 3075c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu target_damage_rect->Union(damage_rect_in_target_space); 3082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 3092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 3102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 3112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void DamageTracker::ExtendDamageForRenderSurface( 312c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch LayerImpl* layer, 313c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch gfx::Rect* target_damage_rect) { 3142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // There are two ways a "descendant surface" can damage regions of the "target 3152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // surface": 3162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // 1. Property change: 3172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // - a surface's geometry can change because of 3182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // - changes to descendants (i.e. the subtree) that affect the 3192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // surface's content rect 3202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // - changes to ancestor layers that propagate their property 3212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // changes to their entire subtree. 3222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // - just like layers, both the old surface rect and new surface rect 3232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // will damage the target surface in this case. 3242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // 3252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // 2. Damage rect: This surface may have been damaged by its own layer_list 3262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // as well, and that damage should propagate to the target surface. 3272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // 3282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 3292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) RenderSurfaceImpl* render_surface = layer->render_surface(); 3302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 3312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) bool surface_is_new = false; 332f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) RectMapData& data = RectDataForLayer(layer->id(), &surface_is_new); 333c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch gfx::Rect old_surface_rect = data.rect_; 3342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 3352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // The drawableContextRect() already includes the replica if it exists. 336c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch gfx::Rect surface_rect_in_target_space = 337c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch gfx::ToEnclosingRect(render_surface->DrawableContentRect()); 338f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) data.Update(surface_rect_in_target_space, mailboxId_); 3392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 340c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch gfx::Rect damage_rect_in_local_space; 3414e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) if (surface_is_new || render_surface->SurfacePropertyChanged()) { 3422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // The entire surface contributes damage. 3432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) damage_rect_in_local_space = render_surface->content_rect(); 3442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 3452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // The surface's old region is now exposed on the target surface, too. 3462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) target_damage_rect->Union(old_surface_rect); 3472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } else { 3482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Only the surface's damage_rect will damage the target surface. 3492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) damage_rect_in_local_space = 3502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) render_surface->damage_tracker()->current_damage_rect(); 3512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 3522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 3532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // If there was damage, transform it to target space, and possibly contribute 3542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // its reflection if needed. 3552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (!damage_rect_in_local_space.IsEmpty()) { 3562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const gfx::Transform& draw_transform = render_surface->draw_transform(); 357c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch gfx::Rect damage_rect_in_target_space = MathUtil::MapEnclosingClippedRect( 358c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch draw_transform, damage_rect_in_local_space); 3592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) target_damage_rect->Union(damage_rect_in_target_space); 3602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 3612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (layer->replica_layer()) { 3622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const gfx::Transform& replica_draw_transform = 3632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) render_surface->replica_draw_transform(); 364c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch target_damage_rect->Union(MathUtil::MapEnclosingClippedRect( 3652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) replica_draw_transform, damage_rect_in_local_space)); 3662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 3672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 3682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 3692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // If there was damage on the replica's mask, then the target surface receives 3702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // that damage as well. 3712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (layer->replica_layer() && layer->replica_layer()->mask_layer()) { 3722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) LayerImpl* replica_mask_layer = layer->replica_layer()->mask_layer(); 3732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 3742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) bool replica_is_new = false; 375f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) RectMapData& data = 376f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) RectDataForLayer(replica_mask_layer->id(), &replica_is_new); 3772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 3782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const gfx::Transform& replica_draw_transform = 3792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) render_surface->replica_draw_transform(); 380c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch gfx::Rect replica_mask_layer_rect = MathUtil::MapEnclosingClippedRect( 381c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch replica_draw_transform, gfx::Rect(replica_mask_layer->bounds())); 382f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) data.Update(replica_mask_layer_rect, mailboxId_); 3832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 3842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // In the current implementation, a change in the replica mask damages the 3852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // entire replica region. 3862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (replica_is_new || 3872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) replica_mask_layer->LayerPropertyChanged() || 3882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) !replica_mask_layer->update_rect().IsEmpty()) 3892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) target_damage_rect->Union(replica_mask_layer_rect); 3902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 3912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 3922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // If the layer has a background filter, this may cause pixels in our surface 3932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // to be expanded, so we will need to expand any damage at or below this 3942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // layer. We expand the damage from this layer too, as we need to readback 3952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // those pixels from the surface with only the contents of layers below this 3962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // one in them. This means we need to redraw any pixels in the surface being 3972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // used for the blur in this layer this frame. 398eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch if (layer->background_filters().HasFilterThatMovesPixels()) { 3992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ExpandDamageRectInsideRectWithFilters(target_damage_rect, 4002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) surface_rect_in_target_space, 4012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) layer->background_filters()); 4022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 4032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 4042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 4052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} // namespace cc 406