| 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 <algorithm> | 7 #include <algorithm> |
| 8 | 8 |
| 9 #include "cc/base/math_util.h" | 9 #include "cc/base/math_util.h" |
| 10 #include "cc/debug/overdraw_metrics.h" | 10 #include "cc/debug/overdraw_metrics.h" |
| 11 #include "cc/layers/layer.h" | 11 #include "cc/layers/layer.h" |
| 12 #include "cc/layers/layer_impl.h" | 12 #include "cc/layers/layer_impl.h" |
| 13 #include "cc/layers/render_surface.h" | 13 #include "cc/layers/render_surface.h" |
| 14 #include "cc/layers/render_surface_impl.h" | 14 #include "cc/layers/render_surface_impl.h" |
| 15 #include "ui/gfx/quad_f.h" | 15 #include "ui/gfx/quad_f.h" |
| 16 #include "ui/gfx/rect_conversions.h" | 16 #include "ui/gfx/rect_conversions.h" |
| 17 | 17 |
| 18 namespace cc { | 18 namespace cc { |
| 19 | 19 |
| 20 template <typename LayerType, typename RenderSurfaceType> | 20 template <typename LayerType, typename RenderSurfaceType> |
| 21 OcclusionTrackerBase<LayerType, RenderSurfaceType>::OcclusionTrackerBase( | 21 OcclusionTrackerBase<LayerType, RenderSurfaceType>::OcclusionTrackerBase( |
| 22 gfx::Rect screen_space_clip_rect, bool record_metrics_for_frame) | 22 const gfx::Rect& screen_space_clip_rect, bool record_metrics_for_frame) |
| 23 : screen_space_clip_rect_(screen_space_clip_rect), | 23 : screen_space_clip_rect_(screen_space_clip_rect), |
| 24 overdraw_metrics_(OverdrawMetrics::Create(record_metrics_for_frame)), | 24 overdraw_metrics_(OverdrawMetrics::Create(record_metrics_for_frame)), |
| 25 occluding_screen_space_rects_(NULL), | 25 occluding_screen_space_rects_(NULL), |
| 26 non_occluding_screen_space_rects_(NULL) {} | 26 non_occluding_screen_space_rects_(NULL) {} |
| 27 | 27 |
| 28 template <typename LayerType, typename RenderSurfaceType> | 28 template <typename LayerType, typename RenderSurfaceType> |
| 29 OcclusionTrackerBase<LayerType, RenderSurfaceType>::~OcclusionTrackerBase() {} | 29 OcclusionTrackerBase<LayerType, RenderSurfaceType>::~OcclusionTrackerBase() {} |
| 30 | 30 |
| 31 template <typename LayerType, typename RenderSurfaceType> | 31 template <typename LayerType, typename RenderSurfaceType> |
| 32 void OcclusionTrackerBase<LayerType, RenderSurfaceType>::EnterLayer( | 32 void OcclusionTrackerBase<LayerType, RenderSurfaceType>::EnterLayer( |
| (...skipping 14 matching lines...) Expand all Loading... |
| 47 if (layer_iterator.represents_itself) | 47 if (layer_iterator.represents_itself) |
| 48 MarkOccludedBehindLayer(layer_iterator.current_layer); | 48 MarkOccludedBehindLayer(layer_iterator.current_layer); |
| 49 // TODO(danakj): This should be done when entering the contributing surface, | 49 // TODO(danakj): This should be done when entering the contributing surface, |
| 50 // but in a way that the surface's own occlusion won't occlude itself. | 50 // but in a way that the surface's own occlusion won't occlude itself. |
| 51 else if (layer_iterator.represents_contributing_render_surface) | 51 else if (layer_iterator.represents_contributing_render_surface) |
| 52 LeaveToRenderTarget(render_target); | 52 LeaveToRenderTarget(render_target); |
| 53 } | 53 } |
| 54 | 54 |
| 55 template <typename RenderSurfaceType> | 55 template <typename RenderSurfaceType> |
| 56 static gfx::Rect ScreenSpaceClipRectInTargetSurface( | 56 static gfx::Rect ScreenSpaceClipRectInTargetSurface( |
| 57 const RenderSurfaceType* target_surface, gfx::Rect screen_space_clip_rect) { | 57 const RenderSurfaceType* target_surface, |
| 58 const gfx::Rect& screen_space_clip_rect) { |
| 58 gfx::Transform inverse_screen_space_transform( | 59 gfx::Transform inverse_screen_space_transform( |
| 59 gfx::Transform::kSkipInitialization); | 60 gfx::Transform::kSkipInitialization); |
| 60 if (!target_surface->screen_space_transform().GetInverse( | 61 if (!target_surface->screen_space_transform().GetInverse( |
| 61 &inverse_screen_space_transform)) | 62 &inverse_screen_space_transform)) |
| 62 return target_surface->content_rect(); | 63 return target_surface->content_rect(); |
| 63 | 64 |
| 64 return gfx::ToEnclosingRect(MathUtil::ProjectClippedRect( | 65 return gfx::ToEnclosingRect(MathUtil::ProjectClippedRect( |
| 65 inverse_screen_space_transform, screen_space_clip_rect)); | 66 inverse_screen_space_transform, screen_space_clip_rect)); |
| 66 } | 67 } |
| 67 | 68 |
| 68 template <typename RenderSurfaceType> | 69 template <typename RenderSurfaceType> |
| 69 static Region TransformSurfaceOpaqueRegion(const Region& region, | 70 static Region TransformSurfaceOpaqueRegion( |
| 70 bool have_clip_rect, | 71 const Region& region, |
| 71 gfx::Rect clip_rect_in_new_target, | 72 bool have_clip_rect, |
| 72 const gfx::Transform& transform) { | 73 const gfx::Rect& clip_rect_in_new_target, |
| 74 const gfx::Transform& transform) { |
| 73 if (region.IsEmpty()) | 75 if (region.IsEmpty()) |
| 74 return Region(); | 76 return Region(); |
| 75 | 77 |
| 76 // Verify that rects within the |surface| will remain rects in its target | 78 // Verify that rects within the |surface| will remain rects in its target |
| 77 // surface after applying |transform|. If this is true, then apply |transform| | 79 // surface after applying |transform|. If this is true, then apply |transform| |
| 78 // to each rect within |region| in order to transform the entire Region. | 80 // to each rect within |region| in order to transform the entire Region. |
| 79 | 81 |
| 80 // TODO(danakj): Find a rect interior to each transformed quad. | 82 // TODO(danakj): Find a rect interior to each transformed quad. |
| 81 if (!transform.Preserves2dAxisAlignment()) | 83 if (!transform.Preserves2dAxisAlignment()) |
| 82 return Region(); | 84 return Region(); |
| (...skipping 149 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 232 stack_.back().occlusion_from_outside_target.Clear(); | 234 stack_.back().occlusion_from_outside_target.Clear(); |
| 233 stack_.back().occlusion_from_inside_target.Clear(); | 235 stack_.back().occlusion_from_inside_target.Clear(); |
| 234 } else if (!SurfaceTransformsToTargetKnown(surface)) { | 236 } else if (!SurfaceTransformsToTargetKnown(surface)) { |
| 235 stack_.back().occlusion_from_inside_target.Clear(); | 237 stack_.back().occlusion_from_inside_target.Clear(); |
| 236 stack_.back().occlusion_from_outside_target.Clear(); | 238 stack_.back().occlusion_from_outside_target.Clear(); |
| 237 } | 239 } |
| 238 } | 240 } |
| 239 | 241 |
| 240 template <typename LayerType> | 242 template <typename LayerType> |
| 241 static void ReduceOcclusionBelowSurface(LayerType* contributing_layer, | 243 static void ReduceOcclusionBelowSurface(LayerType* contributing_layer, |
| 242 gfx::Rect surface_rect, | 244 const gfx::Rect& surface_rect, |
| 243 const gfx::Transform& surface_transform, | 245 const gfx::Transform& surface_transform, |
| 244 LayerType* render_target, | 246 LayerType* render_target, |
| 245 Region* occlusion_from_inside_target) { | 247 Region* occlusion_from_inside_target) { |
| 246 if (surface_rect.IsEmpty()) | 248 if (surface_rect.IsEmpty()) |
| 247 return; | 249 return; |
| 248 | 250 |
| 249 gfx::Rect affected_area_in_target = gfx::ToEnclosingRect( | 251 gfx::Rect affected_area_in_target = gfx::ToEnclosingRect( |
| 250 MathUtil::MapClippedRect(surface_transform, gfx::RectF(surface_rect))); | 252 MathUtil::MapClippedRect(surface_transform, gfx::RectF(surface_rect))); |
| 251 if (contributing_layer->render_surface()->is_clipped()) { | 253 if (contributing_layer->render_surface()->is_clipped()) { |
| 252 affected_area_in_target.Intersect( | 254 affected_area_in_target.Intersect( |
| (...skipping 237 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 490 // box. | 492 // box. |
| 491 gfx::Rect screen_space_rect = | 493 gfx::Rect screen_space_rect = |
| 492 gfx::ToEnclosedRect(screen_space_quad.BoundingBox()); | 494 gfx::ToEnclosedRect(screen_space_quad.BoundingBox()); |
| 493 non_occluding_screen_space_rects_->push_back(screen_space_rect); | 495 non_occluding_screen_space_rects_->push_back(screen_space_rect); |
| 494 } | 496 } |
| 495 } | 497 } |
| 496 | 498 |
| 497 template <typename LayerType, typename RenderSurfaceType> | 499 template <typename LayerType, typename RenderSurfaceType> |
| 498 bool OcclusionTrackerBase<LayerType, RenderSurfaceType>::Occluded( | 500 bool OcclusionTrackerBase<LayerType, RenderSurfaceType>::Occluded( |
| 499 const LayerType* render_target, | 501 const LayerType* render_target, |
| 500 gfx::Rect content_rect, | 502 const gfx::Rect& content_rect, |
| 501 const gfx::Transform& draw_transform, | 503 const gfx::Transform& draw_transform, |
| 502 bool impl_draw_transform_is_unknown) const { | 504 bool impl_draw_transform_is_unknown) const { |
| 503 DCHECK(!stack_.empty()); | 505 DCHECK(!stack_.empty()); |
| 504 if (stack_.empty()) | 506 if (stack_.empty()) |
| 505 return false; | 507 return false; |
| 506 if (content_rect.IsEmpty()) | 508 if (content_rect.IsEmpty()) |
| 507 return true; | 509 return true; |
| 508 if (impl_draw_transform_is_unknown) | 510 if (impl_draw_transform_is_unknown) |
| 509 return false; | 511 return false; |
| 510 | 512 |
| (...skipping 28 matching lines...) Expand all Loading... |
| 539 gfx::RectF unoccluded_rect_in_target_surface = | 541 gfx::RectF unoccluded_rect_in_target_surface = |
| 540 unoccluded_region_in_target_surface.bounds(); | 542 unoccluded_region_in_target_surface.bounds(); |
| 541 | 543 |
| 542 return unoccluded_rect_in_target_surface.IsEmpty(); | 544 return unoccluded_rect_in_target_surface.IsEmpty(); |
| 543 } | 545 } |
| 544 | 546 |
| 545 template <typename LayerType, typename RenderSurfaceType> | 547 template <typename LayerType, typename RenderSurfaceType> |
| 546 gfx::Rect OcclusionTrackerBase<LayerType, RenderSurfaceType>:: | 548 gfx::Rect OcclusionTrackerBase<LayerType, RenderSurfaceType>:: |
| 547 UnoccludedContentRect( | 549 UnoccludedContentRect( |
| 548 const LayerType* render_target, | 550 const LayerType* render_target, |
| 549 gfx::Rect content_rect, | 551 const gfx::Rect& content_rect, |
| 550 const gfx::Transform& draw_transform, | 552 const gfx::Transform& draw_transform, |
| 551 bool impl_draw_transform_is_unknown) const { | 553 bool impl_draw_transform_is_unknown) const { |
| 552 DCHECK(!stack_.empty()); | 554 DCHECK(!stack_.empty()); |
| 553 if (stack_.empty()) | 555 if (stack_.empty()) |
| 554 return content_rect; | 556 return content_rect; |
| 555 if (content_rect.IsEmpty()) | 557 if (content_rect.IsEmpty()) |
| 556 return content_rect; | 558 return content_rect; |
| 557 if (impl_draw_transform_is_unknown) | 559 if (impl_draw_transform_is_unknown) |
| 558 return content_rect; | 560 return content_rect; |
| 559 | 561 |
| (...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 591 unoccluded_rect.Intersect(content_rect); | 593 unoccluded_rect.Intersect(content_rect); |
| 592 | 594 |
| 593 return unoccluded_rect; | 595 return unoccluded_rect; |
| 594 } | 596 } |
| 595 | 597 |
| 596 template <typename LayerType, typename RenderSurfaceType> | 598 template <typename LayerType, typename RenderSurfaceType> |
| 597 gfx::Rect OcclusionTrackerBase<LayerType, RenderSurfaceType>:: | 599 gfx::Rect OcclusionTrackerBase<LayerType, RenderSurfaceType>:: |
| 598 UnoccludedContributingSurfaceContentRect( | 600 UnoccludedContributingSurfaceContentRect( |
| 599 const LayerType* layer, | 601 const LayerType* layer, |
| 600 bool for_replica, | 602 bool for_replica, |
| 601 gfx::Rect content_rect) const { | 603 const gfx::Rect& content_rect) const { |
| 602 DCHECK(!stack_.empty()); | 604 DCHECK(!stack_.empty()); |
| 603 // The layer is a contributing render_target so it should have a surface. | 605 // The layer is a contributing render_target so it should have a surface. |
| 604 DCHECK(layer->render_surface()); | 606 DCHECK(layer->render_surface()); |
| 605 // The layer is a contributing render_target so its target should be itself. | 607 // The layer is a contributing render_target so its target should be itself. |
| 606 DCHECK_EQ(layer->render_target(), layer); | 608 DCHECK_EQ(layer->render_target(), layer); |
| 607 // The layer should not be the root, else what is is contributing to? | 609 // The layer should not be the root, else what is is contributing to? |
| 608 DCHECK(layer->parent()); | 610 DCHECK(layer->parent()); |
| 609 // This should be called while the layer is still considered the current | 611 // This should be called while the layer is still considered the current |
| 610 // target in the occlusion tracker. | 612 // target in the occlusion tracker. |
| 611 DCHECK_EQ(layer, stack_.back().target); | 613 DCHECK_EQ(layer, stack_.back().target); |
| (...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 663 unoccluded_rect.Intersect(content_rect); | 665 unoccluded_rect.Intersect(content_rect); |
| 664 | 666 |
| 665 return unoccluded_rect; | 667 return unoccluded_rect; |
| 666 } | 668 } |
| 667 | 669 |
| 668 // Instantiate (and export) templates here for the linker. | 670 // Instantiate (and export) templates here for the linker. |
| 669 template class OcclusionTrackerBase<Layer, RenderSurface>; | 671 template class OcclusionTrackerBase<Layer, RenderSurface>; |
| 670 template class OcclusionTrackerBase<LayerImpl, RenderSurfaceImpl>; | 672 template class OcclusionTrackerBase<LayerImpl, RenderSurfaceImpl>; |
| 671 | 673 |
| 672 } // namespace cc | 674 } // namespace cc |
| OLD | NEW |