Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(266)

Side by Side Diff: cc/trees/damage_tracker.cc

Issue 2632463005: cc: Ensure that large damage doesn't register as "frame has no damage" (Closed)
Patch Set: update Created 3 years, 11 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « cc/trees/damage_tracker.h ('k') | cc/trees/damage_tracker_unittest.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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
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
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::GetDamageRectIfValid(gfx::Rect* rect) {
144 return current_damage_.GetAsRect(rect);
149 } 145 }
150 146
151 DamageTracker::LayerRectMapData& DamageTracker::RectDataForLayer( 147 DamageTracker::LayerRectMapData& DamageTracker::RectDataForLayer(
152 int layer_id, 148 int layer_id,
153 bool* layer_is_new) { 149 bool* layer_is_new) {
154 LayerRectMapData data(layer_id); 150 LayerRectMapData data(layer_id);
155 151
156 SortedRectMapForLayers::iterator it = std::lower_bound( 152 SortedRectMapForLayers::iterator it = std::lower_bound(
157 rect_history_for_layers_.begin(), rect_history_for_layers_.end(), data); 153 rect_history_for_layers_.begin(), rect_history_for_layers_.end(), data);
158 154
(...skipping 15 matching lines...) Expand all
174 rect_history_for_surfaces_.end(), data); 170 rect_history_for_surfaces_.end(), data);
175 171
176 if (it == rect_history_for_surfaces_.end() || it->surface_id_ != surface_id) { 172 if (it == rect_history_for_surfaces_.end() || it->surface_id_ != surface_id) {
177 *surface_is_new = true; 173 *surface_is_new = true;
178 it = rect_history_for_surfaces_.insert(it, data); 174 it = rect_history_for_surfaces_.insert(it, data);
179 } 175 }
180 176
181 return *it; 177 return *it;
182 } 178 }
183 179
184 gfx::Rect DamageTracker::TrackDamageFromActiveLayers( 180 DamageTracker::DamageAccumulator DamageTracker::TrackDamageFromActiveLayers(
185 const LayerImplList& layer_list, 181 const LayerImplList& layer_list,
186 const RenderSurfaceImpl* target_surface) { 182 const RenderSurfaceImpl* target_surface) {
187 gfx::Rect damage_rect; 183 DamageAccumulator damage;
188 184
189 for (size_t layer_index = 0; layer_index < layer_list.size(); ++layer_index) { 185 for (size_t layer_index = 0; layer_index < layer_list.size(); ++layer_index) {
190 // Visit layers in back-to-front order. 186 // Visit layers in back-to-front order.
191 LayerImpl* layer = layer_list[layer_index]; 187 LayerImpl* layer = layer_list[layer_index];
192 188
193 // We skip damage from the HUD layer because (a) the HUD layer damages the 189 // 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 190 // whole frame and (b) we don't want HUD layer damage to be shown by the
195 // HUD damage rect visualization. 191 // HUD damage rect visualization.
196 if (layer == layer->layer_tree_impl()->hud_layer()) 192 if (layer == layer->layer_tree_impl()->hud_layer())
197 continue; 193 continue;
198 194
199 if (layer->render_surface() && layer->render_surface() != target_surface) 195 if (layer->render_surface() && layer->render_surface() != target_surface)
200 ExtendDamageForRenderSurface(layer->render_surface(), &damage_rect); 196 ExtendDamageForRenderSurface(layer->render_surface(), &damage);
201 else 197 else
202 ExtendDamageForLayer(layer, &damage_rect); 198 ExtendDamageForLayer(layer, &damage);
203 } 199 }
204 200
205 return damage_rect; 201 return damage;
206 } 202 }
207 203
208 gfx::Rect DamageTracker::TrackDamageFromSurfaceMask( 204 DamageTracker::DamageAccumulator DamageTracker::TrackDamageFromSurfaceMask(
209 LayerImpl* target_surface_mask_layer) { 205 LayerImpl* target_surface_mask_layer) {
210 gfx::Rect damage_rect; 206 DamageAccumulator damage;
211 207
212 if (!target_surface_mask_layer) 208 if (!target_surface_mask_layer)
213 return damage_rect; 209 return damage;
214 210
215 // Currently, if there is any change to the mask, we choose to damage the 211 // 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 212 // entire surface. This could potentially be optimized later, but it is not
217 // expected to be a common case. 213 // expected to be a common case.
218 if (target_surface_mask_layer->LayerPropertyChanged() || 214 if (target_surface_mask_layer->LayerPropertyChanged() ||
219 !target_surface_mask_layer->update_rect().IsEmpty()) { 215 !target_surface_mask_layer->update_rect().IsEmpty()) {
220 damage_rect = gfx::Rect(target_surface_mask_layer->bounds()); 216 damage.Union(gfx::Rect(target_surface_mask_layer->bounds()));
221 } 217 }
222 218
223 return damage_rect; 219 return damage;
224 } 220 }
225 221
226 void DamageTracker::PrepareRectHistoryForUpdate() { 222 void DamageTracker::PrepareRectHistoryForUpdate() {
227 mailboxId_++; 223 mailboxId_++;
228 } 224 }
229 225
230 gfx::Rect DamageTracker::TrackDamageFromLeftoverRects() { 226 DamageTracker::DamageAccumulator DamageTracker::TrackDamageFromLeftoverRects() {
231 // After computing damage for all active layers, any leftover items in the 227 // After computing damage for all active layers, any leftover items in the
232 // current rect history correspond to layers/surfaces that no longer exist. 228 // current rect history correspond to layers/surfaces that no longer exist.
233 // So, these regions are now exposed on the target surface. 229 // So, these regions are now exposed on the target surface.
234 230
235 gfx::Rect damage_rect; 231 DamageAccumulator damage;
236 SortedRectMapForLayers::iterator layer_cur_pos = 232 SortedRectMapForLayers::iterator layer_cur_pos =
237 rect_history_for_layers_.begin(); 233 rect_history_for_layers_.begin();
238 SortedRectMapForLayers::iterator layer_copy_pos = layer_cur_pos; 234 SortedRectMapForLayers::iterator layer_copy_pos = layer_cur_pos;
239 SortedRectMapForSurfaces::iterator surface_cur_pos = 235 SortedRectMapForSurfaces::iterator surface_cur_pos =
240 rect_history_for_surfaces_.begin(); 236 rect_history_for_surfaces_.begin();
241 SortedRectMapForSurfaces::iterator surface_copy_pos = surface_cur_pos; 237 SortedRectMapForSurfaces::iterator surface_copy_pos = surface_cur_pos;
242 238
243 // Loop below basically implements std::remove_if loop with and extra 239 // Loop below basically implements std::remove_if loop with and extra
244 // processing (adding deleted rect to damage_rect) for deleted items. 240 // processing (adding deleted rect to damage) for deleted items.
245 // cur_pos iterator runs through all elements of the vector, but copy_pos 241 // 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 242 // 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 243 // not deleted element found then it is copied to the *copy_pos and copy_pos
248 // moved to the next position. 244 // moved to the next position.
249 // If there are no deleted elements then copy_pos iterator is in sync with 245 // If there are no deleted elements then copy_pos iterator is in sync with
250 // cur_pos and no copy happens. 246 // cur_pos and no copy happens.
251 while (layer_cur_pos < rect_history_for_layers_.end()) { 247 while (layer_cur_pos < rect_history_for_layers_.end()) {
252 if (layer_cur_pos->mailboxId_ == mailboxId_) { 248 if (layer_cur_pos->mailboxId_ == mailboxId_) {
253 if (layer_cur_pos != layer_copy_pos) 249 if (layer_cur_pos != layer_copy_pos)
254 *layer_copy_pos = *layer_cur_pos; 250 *layer_copy_pos = *layer_cur_pos;
255 251
256 ++layer_copy_pos; 252 ++layer_copy_pos;
257 } else { 253 } else {
258 damage_rect.Union(layer_cur_pos->rect_); 254 damage.Union(layer_cur_pos->rect_);
259 } 255 }
260 256
261 ++layer_cur_pos; 257 ++layer_cur_pos;
262 } 258 }
263 259
264 while (surface_cur_pos < rect_history_for_surfaces_.end()) { 260 while (surface_cur_pos < rect_history_for_surfaces_.end()) {
265 if (surface_cur_pos->mailboxId_ == mailboxId_) { 261 if (surface_cur_pos->mailboxId_ == mailboxId_) {
266 if (surface_cur_pos != surface_copy_pos) 262 if (surface_cur_pos != surface_copy_pos)
267 *surface_copy_pos = *surface_cur_pos; 263 *surface_copy_pos = *surface_cur_pos;
268 264
269 ++surface_copy_pos; 265 ++surface_copy_pos;
270 } else { 266 } else {
271 damage_rect.Union(surface_cur_pos->rect_); 267 damage.Union(surface_cur_pos->rect_);
272 } 268 }
273 269
274 ++surface_cur_pos; 270 ++surface_cur_pos;
275 } 271 }
276 272
277 if (layer_copy_pos != rect_history_for_layers_.end()) 273 if (layer_copy_pos != rect_history_for_layers_.end())
278 rect_history_for_layers_.erase(layer_copy_pos, 274 rect_history_for_layers_.erase(layer_copy_pos,
279 rect_history_for_layers_.end()); 275 rect_history_for_layers_.end());
280 if (surface_copy_pos != rect_history_for_surfaces_.end()) 276 if (surface_copy_pos != rect_history_for_surfaces_.end())
281 rect_history_for_surfaces_.erase(surface_copy_pos, 277 rect_history_for_surfaces_.erase(surface_copy_pos,
282 rect_history_for_surfaces_.end()); 278 rect_history_for_surfaces_.end());
283 279
284 // If the vector has excessive storage, shrink it 280 // If the vector has excessive storage, shrink it
285 if (rect_history_for_layers_.capacity() > rect_history_for_layers_.size() * 4) 281 if (rect_history_for_layers_.capacity() > rect_history_for_layers_.size() * 4)
286 SortedRectMapForLayers(rect_history_for_layers_) 282 SortedRectMapForLayers(rect_history_for_layers_)
287 .swap(rect_history_for_layers_); 283 .swap(rect_history_for_layers_);
288 if (rect_history_for_surfaces_.capacity() > 284 if (rect_history_for_surfaces_.capacity() >
289 rect_history_for_surfaces_.size() * 4) 285 rect_history_for_surfaces_.size() * 4)
290 SortedRectMapForSurfaces(rect_history_for_surfaces_) 286 SortedRectMapForSurfaces(rect_history_for_surfaces_)
291 .swap(rect_history_for_surfaces_); 287 .swap(rect_history_for_surfaces_);
292 288
293 return damage_rect; 289 return damage;
290 }
291
292 void DamageTracker::ExpandDamageInsideRectWithFilters(
293 const gfx::Rect& pre_filter_rect,
294 const FilterOperations& filters,
295 DamageAccumulator* damage) {
296 gfx::Rect damage_rect;
297 bool is_valid_rect = damage->GetAsRect(&damage_rect);
298 // If the input isn't a valid rect, then there is no point in trying to make
299 // it bigger.
300 if (!is_valid_rect)
301 return;
302
303 // Compute the pixels in the background of the surface that could be affected
304 // by the damage in the content below.
305 gfx::Rect expanded_damage_rect = filters.MapRect(damage_rect, SkMatrix::I());
306
307 // Restrict it to the rectangle in which the background filter is shown.
308 expanded_damage_rect.Intersect(pre_filter_rect);
309
310 damage->Union(expanded_damage_rect);
294 } 311 }
295 312
296 void DamageTracker::ExtendDamageForLayer(LayerImpl* layer, 313 void DamageTracker::ExtendDamageForLayer(LayerImpl* layer,
297 gfx::Rect* target_damage_rect) { 314 DamageAccumulator* target_damage) {
298 // There are two ways that a layer can damage a region of the target surface: 315 // There are two ways that a layer can damage a region of the target surface:
299 // 1. Property change (e.g. opacity, position, transforms): 316 // 1. Property change (e.g. opacity, position, transforms):
300 // - the entire region of the layer itself damages the surface. 317 // - the entire region of the layer itself damages the surface.
301 // - the old layer region also damages the surface, because this region 318 // - the old layer region also damages the surface, because this region
302 // is now exposed. 319 // is now exposed.
303 // - note that in many cases the old and new layer rects may overlap, 320 // - note that in many cases the old and new layer rects may overlap,
304 // which is fine. 321 // which is fine.
305 // 322 //
306 // 2. Repaint/update: If a region of the layer that was repainted/updated, 323 // 2. Repaint/update: If a region of the layer that was repainted/updated,
307 // that region damages the surface. 324 // that region damages the surface.
308 // 325 //
309 // Property changes take priority over update rects. 326 // Property changes take priority over update rects.
310 // 327 //
311 // This method is called when we want to consider how a layer contributes to 328 // 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 329 // its target RenderSurface, even if that layer owns the target RenderSurface
313 // itself. To consider how a layer's target surface contributes to the 330 // itself. To consider how a layer's target surface contributes to the
314 // ancestor surface, ExtendDamageForRenderSurface() must be called instead. 331 // ancestor surface, ExtendDamageForRenderSurface() must be called instead.
315 332
316 bool layer_is_new = false; 333 bool layer_is_new = false;
317 LayerRectMapData& data = RectDataForLayer(layer->id(), &layer_is_new); 334 LayerRectMapData& data = RectDataForLayer(layer->id(), &layer_is_new);
318 gfx::Rect old_rect_in_target_space = data.rect_; 335 gfx::Rect old_rect_in_target_space = data.rect_;
319 336
320 gfx::Rect rect_in_target_space = layer->GetEnclosingRectInTargetSpace(); 337 gfx::Rect rect_in_target_space = layer->GetEnclosingRectInTargetSpace();
321 data.Update(rect_in_target_space, mailboxId_); 338 data.Update(rect_in_target_space, mailboxId_);
322 339
323 if (layer_is_new || layer->LayerPropertyChanged()) { 340 if (layer_is_new || layer->LayerPropertyChanged()) {
324 // If a layer is new or has changed, then its entire layer rect affects the 341 // If a layer is new or has changed, then its entire layer rect affects the
325 // target surface. 342 // target surface.
326 target_damage_rect->Union(rect_in_target_space); 343 target_damage->Union(rect_in_target_space);
327 344
328 // The layer's old region is now exposed on the target surface, too. 345 // 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. 346 // Note old_rect_in_target_space is already in target space.
330 target_damage_rect->Union(old_rect_in_target_space); 347 target_damage->Union(old_rect_in_target_space);
331 return; 348 return;
332 } 349 }
333 350
334 // If the layer properties haven't changed, then the the target surface is 351 // 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. 352 // only affected by the layer's damaged area, which could be empty.
336 gfx::Rect damage_rect = 353 gfx::Rect damage_rect =
337 gfx::UnionRects(layer->update_rect(), layer->damage_rect()); 354 gfx::UnionRects(layer->update_rect(), layer->damage_rect());
338 damage_rect.Intersect(gfx::Rect(layer->bounds())); 355 damage_rect.Intersect(gfx::Rect(layer->bounds()));
339 if (!damage_rect.IsEmpty()) { 356 if (!damage_rect.IsEmpty()) {
340 gfx::Rect damage_rect_in_target_space = 357 gfx::Rect damage_rect_in_target_space =
341 MathUtil::MapEnclosingClippedRect(layer->DrawTransform(), damage_rect); 358 MathUtil::MapEnclosingClippedRect(layer->DrawTransform(), damage_rect);
342 target_damage_rect->Union(damage_rect_in_target_space); 359 target_damage->Union(damage_rect_in_target_space);
343 } 360 }
344 } 361 }
345 362
346 void DamageTracker::ExtendDamageForRenderSurface( 363 void DamageTracker::ExtendDamageForRenderSurface(
347 RenderSurfaceImpl* render_surface, 364 RenderSurfaceImpl* render_surface,
348 gfx::Rect* target_damage_rect) { 365 DamageAccumulator* target_damage) {
349 // There are two ways a "descendant surface" can damage regions of the "target 366 // There are two ways a "descendant surface" can damage regions of the "target
350 // surface": 367 // surface":
351 // 1. Property change: 368 // 1. Property change:
352 // - a surface's geometry can change because of 369 // - a surface's geometry can change because of
353 // - changes to descendants (i.e. the subtree) that affect the 370 // - changes to descendants (i.e. the subtree) that affect the
354 // surface's content rect 371 // surface's content rect
355 // - changes to ancestor layers that propagate their property 372 // - changes to ancestor layers that propagate their property
356 // changes to their entire subtree. 373 // changes to their entire subtree.
357 // - just like layers, both the old surface rect and new surface rect 374 // - just like layers, both the old surface rect and new surface rect
358 // will damage the target surface in this case. 375 // will damage the target surface in this case.
359 // 376 //
360 // 2. Damage rect: This surface may have been damaged by its own layer_list 377 // 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. 378 // as well, and that damage should propagate to the target surface.
362 // 379 //
363 380
364 bool surface_is_new = false; 381 bool surface_is_new = false;
365 SurfaceRectMapData& data = 382 SurfaceRectMapData& data =
366 RectDataForSurface(render_surface->id(), &surface_is_new); 383 RectDataForSurface(render_surface->id(), &surface_is_new);
367 gfx::Rect old_surface_rect = data.rect_; 384 gfx::Rect old_surface_rect = data.rect_;
368 385
369 gfx::Rect surface_rect_in_target_space = 386 gfx::Rect surface_rect_in_target_space =
370 gfx::ToEnclosingRect(render_surface->DrawableContentRect()); 387 gfx::ToEnclosingRect(render_surface->DrawableContentRect());
371 data.Update(surface_rect_in_target_space, mailboxId_); 388 data.Update(surface_rect_in_target_space, mailboxId_);
372 389
373 if (surface_is_new || render_surface->SurfacePropertyChanged()) { 390 if (surface_is_new || render_surface->SurfacePropertyChanged()) {
374 // The entire surface contributes damage. 391 // The entire surface contributes damage.
375 target_damage_rect->Union(surface_rect_in_target_space); 392 target_damage->Union(surface_rect_in_target_space);
376 393
377 // The surface's old region is now exposed on the target surface, too. 394 // The surface's old region is now exposed on the target surface, too.
378 target_damage_rect->Union(old_surface_rect); 395 target_damage->Union(old_surface_rect);
379 } else { 396 } else {
380 // Only the surface's damage_rect will damage the target surface. 397 // Only the surface's damage_rect will damage the target surface.
381 gfx::Rect damage_rect_in_local_space = 398 gfx::Rect damage_rect_in_local_space;
382 render_surface->damage_tracker()->current_damage_rect(); 399 bool is_valid_rect = render_surface->damage_tracker()->GetDamageRectIfValid(
383 400 &damage_rect_in_local_space);
384 // If there was damage, transform it to target space, and possibly 401 if (is_valid_rect && !damage_rect_in_local_space.IsEmpty()) {
385 // contribute its reflection if needed. 402 // If there was damage, transform it to target space, and possibly
386 if (!damage_rect_in_local_space.IsEmpty()) { 403 // contribute its reflection if needed.
387 const gfx::Transform& draw_transform = render_surface->draw_transform(); 404 const gfx::Transform& draw_transform = render_surface->draw_transform();
388 gfx::Rect damage_rect_in_target_space = MathUtil::MapEnclosingClippedRect( 405 gfx::Rect damage_rect_in_target_space = MathUtil::MapEnclosingClippedRect(
389 draw_transform, damage_rect_in_local_space); 406 draw_transform, damage_rect_in_local_space);
390 target_damage_rect->Union(damage_rect_in_target_space); 407 target_damage->Union(damage_rect_in_target_space);
408 } else if (!is_valid_rect) {
409 target_damage->Union(surface_rect_in_target_space);
391 } 410 }
392 } 411 }
393 412
394 // If the layer has a background filter, this may cause pixels in our surface 413 // 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 414 // 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 415 // 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 416 // 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 417 // 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. 418 // used for the blur in this layer this frame.
400 const FilterOperations& background_filters = 419 const FilterOperations& background_filters =
401 render_surface->BackgroundFilters(); 420 render_surface->BackgroundFilters();
402 if (background_filters.HasFilterThatMovesPixels()) { 421 if (background_filters.HasFilterThatMovesPixels()) {
403 ExpandDamageRectInsideRectWithFilters( 422 ExpandDamageInsideRectWithFilters(surface_rect_in_target_space,
404 target_damage_rect, surface_rect_in_target_space, background_filters); 423 background_filters, target_damage);
405 } 424 }
406 } 425 }
407 426
427 bool DamageTracker::DamageAccumulator::GetAsRect(gfx::Rect* rect) {
428 if (!is_valid_rect_)
429 return false;
430
431 base::CheckedNumeric<int> width = right_;
432 width -= x_;
433 base::CheckedNumeric<int> height = bottom_;
434 height -= y_;
435 if (!width.IsValid() || !height.IsValid()) {
436 is_valid_rect_ = false;
437 return false;
438 }
439
440 rect->set_x(x_);
441 rect->set_y(y_);
442 rect->set_width(width.ValueOrDie());
443 rect->set_height(height.ValueOrDie());
444 return true;
445 }
446
408 } // namespace cc 447 } // namespace cc
OLDNEW
« no previous file with comments | « cc/trees/damage_tracker.h ('k') | cc/trees/damage_tracker_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698