OLD | NEW |
1 // Copyright 2012 The Chromium Authors. All rights reserved. | 1 // Copyright 2012 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/occlusion_tracker.h" | 5 #include "cc/trees/occlusion_tracker.h" |
6 | 6 |
7 #include <stddef.h> | 7 #include <stddef.h> |
8 | 8 |
9 #include <algorithm> | 9 #include <algorithm> |
10 | 10 |
(...skipping 92 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
103 MathUtil::MapEnclosedRectWith2dAxisAlignedTransform(transform, | 103 MathUtil::MapEnclosedRectWith2dAxisAlignedTransform(transform, |
104 region.GetRect(i)); | 104 region.GetRect(i)); |
105 if (have_clip_rect) | 105 if (have_clip_rect) |
106 transformed_rect.Intersect(clip_rect_in_new_target); | 106 transformed_rect.Intersect(clip_rect_in_new_target); |
107 transformed_region.Union(transformed_rect); | 107 transformed_region.Union(transformed_rect); |
108 } | 108 } |
109 return transformed_region; | 109 return transformed_region; |
110 } | 110 } |
111 | 111 |
112 void OcclusionTracker::EnterRenderTarget(const LayerImpl* new_target) { | 112 void OcclusionTracker::EnterRenderTarget(const LayerImpl* new_target) { |
113 if (!stack_.empty() && stack_.back().target == new_target) | 113 DCHECK(new_target->has_render_surface()); |
| 114 if (!stack_.empty() && stack_.back().target == new_target->render_surface()) |
114 return; | 115 return; |
115 | 116 |
116 const LayerImpl* old_target = NULL; | 117 const RenderSurfaceImpl* old_target_surface = NULL; |
117 const RenderSurfaceImpl* old_occlusion_immune_ancestor = NULL; | 118 const RenderSurfaceImpl* old_occlusion_immune_ancestor = NULL; |
118 if (!stack_.empty()) { | 119 if (!stack_.empty()) { |
119 old_target = stack_.back().target; | 120 old_target_surface = stack_.back().target; |
120 old_occlusion_immune_ancestor = | 121 old_occlusion_immune_ancestor = |
121 old_target->render_surface()->nearest_occlusion_immune_ancestor(); | 122 old_target_surface->nearest_occlusion_immune_ancestor(); |
122 } | 123 } |
123 const RenderSurfaceImpl* new_occlusion_immune_ancestor = | 124 const RenderSurfaceImpl* new_occlusion_immune_ancestor = |
124 new_target->render_surface()->nearest_occlusion_immune_ancestor(); | 125 new_target->render_surface()->nearest_occlusion_immune_ancestor(); |
125 | 126 |
126 stack_.push_back(StackObject(new_target)); | 127 stack_.push_back(StackObject(new_target->render_surface())); |
127 | 128 |
128 // We copy the screen occlusion into the new RenderSurfaceImpl subtree, but we | 129 // We copy the screen occlusion into the new RenderSurfaceImpl subtree, but we |
129 // never copy in the occlusion from inside the target, since we are looking | 130 // never copy in the occlusion from inside the target, since we are looking |
130 // at a new RenderSurfaceImpl target. | 131 // at a new RenderSurfaceImpl target. |
131 | 132 |
132 // If entering an unoccluded subtree, do not carry forward the outside | 133 // If entering an unoccluded subtree, do not carry forward the outside |
133 // occlusion calculated so far. | 134 // occlusion calculated so far. |
134 bool entering_unoccluded_subtree = | 135 bool entering_unoccluded_subtree = |
135 new_occlusion_immune_ancestor && | 136 new_occlusion_immune_ancestor && |
136 new_occlusion_immune_ancestor != old_occlusion_immune_ancestor; | 137 new_occlusion_immune_ancestor != old_occlusion_immune_ancestor; |
(...skipping 12 matching lines...) Expand all Loading... |
149 stack_.size() > 1 && | 150 stack_.size() > 1 && |
150 !entering_unoccluded_subtree && | 151 !entering_unoccluded_subtree && |
151 have_transform_from_screen_to_new_target && | 152 have_transform_from_screen_to_new_target && |
152 !entering_root_target; | 153 !entering_root_target; |
153 if (!copy_outside_occlusion_forward) | 154 if (!copy_outside_occlusion_forward) |
154 return; | 155 return; |
155 | 156 |
156 size_t last_index = stack_.size() - 1; | 157 size_t last_index = stack_.size() - 1; |
157 gfx::Transform old_target_to_new_target_transform( | 158 gfx::Transform old_target_to_new_target_transform( |
158 inverse_new_target_screen_space_transform, | 159 inverse_new_target_screen_space_transform, |
159 old_target->render_surface()->screen_space_transform()); | 160 old_target_surface->screen_space_transform()); |
160 stack_[last_index].occlusion_from_outside_target = | 161 stack_[last_index].occlusion_from_outside_target = |
161 TransformSurfaceOpaqueRegion( | 162 TransformSurfaceOpaqueRegion( |
162 stack_[last_index - 1].occlusion_from_outside_target, false, | 163 stack_[last_index - 1].occlusion_from_outside_target, false, |
163 gfx::Rect(), old_target_to_new_target_transform); | 164 gfx::Rect(), old_target_to_new_target_transform); |
164 stack_[last_index].occlusion_from_outside_target.Union( | 165 stack_[last_index].occlusion_from_outside_target.Union( |
165 TransformSurfaceOpaqueRegion( | 166 TransformSurfaceOpaqueRegion( |
166 stack_[last_index - 1].occlusion_from_inside_target, false, | 167 stack_[last_index - 1].occlusion_from_inside_target, false, |
167 gfx::Rect(), old_target_to_new_target_transform)); | 168 gfx::Rect(), old_target_to_new_target_transform)); |
168 } | 169 } |
169 | 170 |
(...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
239 | 240 |
240 occlusion_rect.Inset(shrink_left, shrink_top, shrink_right, shrink_bottom); | 241 occlusion_rect.Inset(shrink_left, shrink_top, shrink_right, shrink_bottom); |
241 | 242 |
242 occlusion_from_inside_target->Union(occlusion_rect); | 243 occlusion_from_inside_target->Union(occlusion_rect); |
243 } | 244 } |
244 } | 245 } |
245 | 246 |
246 void OcclusionTracker::LeaveToRenderTarget(const LayerImpl* new_target) { | 247 void OcclusionTracker::LeaveToRenderTarget(const LayerImpl* new_target) { |
247 DCHECK(!stack_.empty()); | 248 DCHECK(!stack_.empty()); |
248 size_t last_index = stack_.size() - 1; | 249 size_t last_index = stack_.size() - 1; |
| 250 DCHECK(new_target->has_render_surface()); |
249 bool surface_will_be_at_top_after_pop = | 251 bool surface_will_be_at_top_after_pop = |
250 stack_.size() > 1 && stack_[last_index - 1].target == new_target; | 252 stack_.size() > 1 && |
| 253 stack_[last_index - 1].target == new_target->render_surface(); |
251 | 254 |
252 // We merge the screen occlusion from the current RenderSurfaceImpl subtree | 255 // We merge the screen occlusion from the current RenderSurfaceImpl subtree |
253 // out to its parent target RenderSurfaceImpl. The target occlusion can be | 256 // out to its parent target RenderSurfaceImpl. The target occlusion can be |
254 // merged out as well but needs to be transformed to the new target. | 257 // merged out as well but needs to be transformed to the new target. |
255 | 258 |
256 const LayerImpl* old_target = stack_[last_index].target; | 259 const RenderSurfaceImpl* old_surface = stack_[last_index].target; |
257 const RenderSurfaceImpl* old_surface = old_target->render_surface(); | 260 const LayerImpl* old_target = |
| 261 new_target->layer_tree_impl()->LayerById(old_surface->OwningLayerId()); |
258 | 262 |
259 SimpleEnclosedRegion old_occlusion_from_inside_target_in_new_target = | 263 SimpleEnclosedRegion old_occlusion_from_inside_target_in_new_target = |
260 TransformSurfaceOpaqueRegion( | 264 TransformSurfaceOpaqueRegion( |
261 stack_[last_index].occlusion_from_inside_target, | 265 stack_[last_index].occlusion_from_inside_target, |
262 old_surface->is_clipped(), old_surface->clip_rect(), | 266 old_surface->is_clipped(), old_surface->clip_rect(), |
263 old_surface->draw_transform()); | 267 old_surface->draw_transform()); |
264 if (old_target->has_replica() && !old_target->replica_has_mask()) { | 268 if (old_target->has_replica() && !old_target->replica_has_mask()) { |
265 old_occlusion_from_inside_target_in_new_target.Union( | 269 old_occlusion_from_inside_target_in_new_target.Union( |
266 TransformSurfaceOpaqueRegion( | 270 TransformSurfaceOpaqueRegion( |
267 stack_[last_index].occlusion_from_inside_target, | 271 stack_[last_index].occlusion_from_inside_target, |
(...skipping 27 matching lines...) Expand all Loading... |
295 old_occlusion_from_inside_target_in_new_target); | 299 old_occlusion_from_inside_target_in_new_target); |
296 // TODO(danakj): Strictly this should subtract the inside target occlusion | 300 // TODO(danakj): Strictly this should subtract the inside target occlusion |
297 // before union. | 301 // before union. |
298 if (!new_target->layer_tree_impl()->IsRootLayer(new_target)) { | 302 if (!new_target->layer_tree_impl()->IsRootLayer(new_target)) { |
299 stack_[last_index - 1].occlusion_from_outside_target.Union( | 303 stack_[last_index - 1].occlusion_from_outside_target.Union( |
300 old_occlusion_from_outside_target_in_new_target); | 304 old_occlusion_from_outside_target_in_new_target); |
301 } | 305 } |
302 stack_.pop_back(); | 306 stack_.pop_back(); |
303 } else { | 307 } else { |
304 // Replace the top of the stack with the new pushed surface. | 308 // Replace the top of the stack with the new pushed surface. |
305 stack_.back().target = new_target; | 309 stack_.back().target = new_target->render_surface(); |
306 stack_.back().occlusion_from_inside_target = | 310 stack_.back().occlusion_from_inside_target = |
307 old_occlusion_from_inside_target_in_new_target; | 311 old_occlusion_from_inside_target_in_new_target; |
308 if (!new_target->layer_tree_impl()->IsRootLayer(new_target)) { | 312 if (!new_target->layer_tree_impl()->IsRootLayer(new_target)) { |
309 stack_.back().occlusion_from_outside_target = | 313 stack_.back().occlusion_from_outside_target = |
310 old_occlusion_from_outside_target_in_new_target; | 314 old_occlusion_from_outside_target_in_new_target; |
311 } else { | 315 } else { |
312 stack_.back().occlusion_from_outside_target.Clear(); | 316 stack_.back().occlusion_from_outside_target.Clear(); |
313 } | 317 } |
314 } | 318 } |
315 | 319 |
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
359 return; | 363 return; |
360 | 364 |
361 DCHECK(layer->visible_layer_rect().Contains(opaque_layer_region.bounds())); | 365 DCHECK(layer->visible_layer_rect().Contains(opaque_layer_region.bounds())); |
362 | 366 |
363 gfx::Transform draw_transform = layer->DrawTransform(); | 367 gfx::Transform draw_transform = layer->DrawTransform(); |
364 // TODO(danakj): Find a rect interior to each transformed quad. | 368 // TODO(danakj): Find a rect interior to each transformed quad. |
365 if (!draw_transform.Preserves2dAxisAlignment()) | 369 if (!draw_transform.Preserves2dAxisAlignment()) |
366 return; | 370 return; |
367 | 371 |
368 gfx::Rect clip_rect_in_target = ScreenSpaceClipRectInTargetSurface( | 372 gfx::Rect clip_rect_in_target = ScreenSpaceClipRectInTargetSurface( |
369 layer->render_target()->render_surface(), screen_space_clip_rect_); | 373 layer->render_target(), screen_space_clip_rect_); |
370 if (layer->is_clipped()) { | 374 if (layer->is_clipped()) { |
371 clip_rect_in_target.Intersect(layer->clip_rect()); | 375 clip_rect_in_target.Intersect(layer->clip_rect()); |
372 } else { | 376 } else { |
373 clip_rect_in_target.Intersect( | 377 clip_rect_in_target.Intersect(layer->render_target()->content_rect()); |
374 layer->render_target()->render_surface()->content_rect()); | |
375 } | 378 } |
376 | 379 |
377 for (size_t i = 0; i < opaque_layer_region.GetRegionComplexity(); ++i) { | 380 for (size_t i = 0; i < opaque_layer_region.GetRegionComplexity(); ++i) { |
378 gfx::Rect transformed_rect = | 381 gfx::Rect transformed_rect = |
379 MathUtil::MapEnclosedRectWith2dAxisAlignedTransform( | 382 MathUtil::MapEnclosedRectWith2dAxisAlignedTransform( |
380 draw_transform, opaque_layer_region.GetRect(i)); | 383 draw_transform, opaque_layer_region.GetRect(i)); |
381 transformed_rect.Intersect(clip_rect_in_target); | 384 transformed_rect.Intersect(clip_rect_in_target); |
382 if (transformed_rect.width() < minimum_tracking_size_.width() && | 385 if (transformed_rect.width() < minimum_tracking_size_.width() && |
383 transformed_rect.height() < minimum_tracking_size_.height()) | 386 transformed_rect.height() < minimum_tracking_size_.height()) |
384 continue; | 387 continue; |
385 stack_.back().occlusion_from_inside_target.Union(transformed_rect); | 388 stack_.back().occlusion_from_inside_target.Union(transformed_rect); |
386 } | 389 } |
387 } | 390 } |
388 | 391 |
389 Region OcclusionTracker::ComputeVisibleRegionInScreen() const { | 392 Region OcclusionTracker::ComputeVisibleRegionInScreen( |
390 DCHECK(stack_.back().target->layer_tree_impl()->IsRootLayer( | 393 const LayerTreeImpl* layer_tree) const { |
391 stack_.back().target)); | 394 DCHECK(layer_tree->root_layer()->render_surface() == stack_.back().target); |
392 const SimpleEnclosedRegion& occluded = | 395 const SimpleEnclosedRegion& occluded = |
393 stack_.back().occlusion_from_inside_target; | 396 stack_.back().occlusion_from_inside_target; |
394 Region visible_region(screen_space_clip_rect_); | 397 Region visible_region(screen_space_clip_rect_); |
395 for (size_t i = 0; i < occluded.GetRegionComplexity(); ++i) | 398 for (size_t i = 0; i < occluded.GetRegionComplexity(); ++i) |
396 visible_region.Subtract(occluded.GetRect(i)); | 399 visible_region.Subtract(occluded.GetRect(i)); |
397 return visible_region; | 400 return visible_region; |
398 } | 401 } |
399 | 402 |
400 } // namespace cc | 403 } // namespace cc |
OLD | NEW |