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

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

Issue 1976413002: cc : Fix damage rect bug caused by deletion of render surface (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 4 years, 7 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 135 matching lines...) Expand 10 before | Expand all | Expand 10 after
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
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
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
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
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
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