Chromium Code Reviews| 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" |
| (...skipping 490 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 501 gfx::ToEnclosedRect(screen_space_quad.BoundingBox()); | 501 gfx::ToEnclosedRect(screen_space_quad.BoundingBox()); |
| 502 non_occluding_screen_space_rects_->push_back(screen_space_rect); | 502 non_occluding_screen_space_rects_->push_back(screen_space_rect); |
| 503 } | 503 } |
| 504 } | 504 } |
| 505 | 505 |
| 506 template <typename LayerType, typename RenderSurfaceType> | 506 template <typename LayerType, typename RenderSurfaceType> |
| 507 bool OcclusionTrackerBase<LayerType, RenderSurfaceType>::Occluded( | 507 bool OcclusionTrackerBase<LayerType, RenderSurfaceType>::Occluded( |
| 508 const LayerType* render_target, | 508 const LayerType* render_target, |
| 509 gfx::Rect content_rect, | 509 gfx::Rect content_rect, |
| 510 const gfx::Transform& draw_transform, | 510 const gfx::Transform& draw_transform, |
| 511 bool impl_draw_transform_is_unknown, | 511 bool impl_draw_transform_is_unknown) const { |
| 512 bool is_clipped, | |
| 513 gfx::Rect clip_rect_in_target) const { | |
| 514 if (prevent_occlusion_) | 512 if (prevent_occlusion_) |
| 515 return false; | 513 return false; |
| 516 | 514 |
| 517 DCHECK(!stack_.empty()); | 515 DCHECK(!stack_.empty()); |
| 518 if (stack_.empty()) | 516 if (stack_.empty()) |
| 519 return false; | 517 return false; |
| 520 if (content_rect.IsEmpty()) | 518 if (content_rect.IsEmpty()) |
| 521 return true; | 519 return true; |
| 522 if (impl_draw_transform_is_unknown) | 520 if (impl_draw_transform_is_unknown) |
| 523 return false; | 521 return false; |
| 524 | 522 |
| 525 // For tests with no render target. | 523 // For tests with no render target. |
| 526 if (!render_target) | 524 if (!render_target) |
| 527 return false; | 525 return false; |
| 528 | 526 |
| 529 DCHECK_EQ(render_target->render_target(), render_target); | 527 DCHECK_EQ(render_target->render_target(), render_target); |
| 530 DCHECK(render_target->render_surface()); | 528 DCHECK(render_target->render_surface()); |
| 531 DCHECK_EQ(render_target, stack_.back().target); | 529 DCHECK_EQ(render_target, stack_.back().target); |
| 532 | 530 |
| 531 if (stack_.back().occlusion_from_inside_target.IsEmpty() && | |
| 532 stack_.back().occlusion_from_outside_target.IsEmpty()) { | |
| 533 return false; | |
| 534 } | |
| 535 | |
| 533 gfx::Transform inverse_draw_transform(gfx::Transform::kSkipInitialization); | 536 gfx::Transform inverse_draw_transform(gfx::Transform::kSkipInitialization); |
| 534 if (!draw_transform.GetInverse(&inverse_draw_transform)) | 537 if (!draw_transform.GetInverse(&inverse_draw_transform)) |
| 535 return false; | 538 return false; |
| 536 | 539 |
| 537 // Take the ToEnclosingRect at each step, as we want to contain any unoccluded | 540 // Take the ToEnclosingRect at each step, as we want to contain any unoccluded |
| 538 // partial pixels in the resulting Rect. | 541 // partial pixels in the resulting Rect. |
| 539 Region unoccluded_region_in_target_surface = gfx::ToEnclosingRect( | 542 Region unoccluded_region_in_target_surface = gfx::ToEnclosingRect( |
| 540 MathUtil::MapClippedRect(draw_transform, gfx::RectF(content_rect))); | 543 MathUtil::MapClippedRect(draw_transform, gfx::RectF(content_rect))); |
| 541 // Layers can't clip across surfaces, so count this as internal occlusion. | |
| 542 if (is_clipped) | |
| 543 unoccluded_region_in_target_surface.Intersect(clip_rect_in_target); | |
| 544 unoccluded_region_in_target_surface.Subtract( | 544 unoccluded_region_in_target_surface.Subtract( |
| 545 stack_.back().occlusion_from_inside_target); | 545 stack_.back().occlusion_from_inside_target); |
| 546 gfx::RectF unoccluded_rect_in_target_surface_without_outside_occlusion = | 546 gfx::RectF unoccluded_rect_in_target_surface_without_outside_occlusion = |
| 547 unoccluded_region_in_target_surface.bounds(); | 547 unoccluded_region_in_target_surface.bounds(); |
| 548 unoccluded_region_in_target_surface.Subtract( | 548 unoccluded_region_in_target_surface.Subtract( |
| 549 stack_.back().occlusion_from_outside_target); | 549 stack_.back().occlusion_from_outside_target); |
| 550 | 550 |
| 551 // Treat other clipping as occlusion from outside the surface. | |
| 552 // TODO(danakj): Clip to visibleContentRect? | |
| 553 unoccluded_region_in_target_surface.Intersect( | |
| 554 render_target->render_surface()->content_rect()); | |
| 555 unoccluded_region_in_target_surface.Intersect( | |
| 556 ScreenSpaceClipRectInTargetSurface(render_target->render_surface(), | |
| 557 screen_space_clip_rect_)); | |
| 558 | |
| 559 gfx::RectF unoccluded_rect_in_target_surface = | 551 gfx::RectF unoccluded_rect_in_target_surface = |
| 560 unoccluded_region_in_target_surface.bounds(); | 552 unoccluded_region_in_target_surface.bounds(); |
| 561 | 553 |
| 562 return unoccluded_rect_in_target_surface.IsEmpty(); | 554 return unoccluded_rect_in_target_surface.IsEmpty(); |
| 563 } | 555 } |
| 564 | 556 |
| 565 template <typename LayerType, typename RenderSurfaceType> | 557 template <typename LayerType, typename RenderSurfaceType> |
| 566 gfx::Rect OcclusionTrackerBase<LayerType, RenderSurfaceType>:: | 558 gfx::Rect OcclusionTrackerBase<LayerType, RenderSurfaceType>:: |
| 567 UnoccludedContentRect( | 559 UnoccludedContentRect( |
| 568 const LayerType* render_target, | 560 const LayerType* render_target, |
| 569 gfx::Rect content_rect, | 561 gfx::Rect content_rect, |
| 570 const gfx::Transform& draw_transform, | 562 const gfx::Transform& draw_transform, |
| 571 bool impl_draw_transform_is_unknown, | 563 bool impl_draw_transform_is_unknown) const { |
| 572 bool is_clipped, | |
| 573 gfx::Rect clip_rect_in_target) const { | |
| 574 if (prevent_occlusion_) | 564 if (prevent_occlusion_) |
| 575 return content_rect; | 565 return content_rect; |
| 576 | 566 |
| 577 DCHECK(!stack_.empty()); | 567 DCHECK(!stack_.empty()); |
| 578 if (stack_.empty()) | 568 if (stack_.empty()) |
| 579 return content_rect; | 569 return content_rect; |
| 580 if (content_rect.IsEmpty()) | 570 if (content_rect.IsEmpty()) |
| 581 return content_rect; | 571 return content_rect; |
| 582 if (impl_draw_transform_is_unknown) | 572 if (impl_draw_transform_is_unknown) |
| 583 return content_rect; | 573 return content_rect; |
| 584 | 574 |
| 585 // For tests with no render target. | 575 // For tests with no render target. |
| 586 if (!render_target) | 576 if (!render_target) |
| 587 return content_rect; | 577 return content_rect; |
| 588 | 578 |
| 589 DCHECK_EQ(render_target->render_target(), render_target); | 579 DCHECK_EQ(render_target->render_target(), render_target); |
| 590 DCHECK(render_target->render_surface()); | 580 DCHECK(render_target->render_surface()); |
| 591 DCHECK_EQ(render_target, stack_.back().target); | 581 DCHECK_EQ(render_target, stack_.back().target); |
| 592 | 582 |
| 583 if (stack_.back().occlusion_from_inside_target.IsEmpty() && | |
| 584 stack_.back().occlusion_from_outside_target.IsEmpty()) { | |
| 585 return content_rect; | |
| 586 } | |
| 587 | |
| 593 gfx::Transform inverse_draw_transform(gfx::Transform::kSkipInitialization); | 588 gfx::Transform inverse_draw_transform(gfx::Transform::kSkipInitialization); |
| 594 if (!draw_transform.GetInverse(&inverse_draw_transform)) | 589 if (!draw_transform.GetInverse(&inverse_draw_transform)) |
| 595 return content_rect; | 590 return content_rect; |
| 596 | 591 |
| 597 // Take the ToEnclosingRect at each step, as we want to contain any unoccluded | 592 // Take the ToEnclosingRect at each step, as we want to contain any unoccluded |
| 598 // partial pixels in the resulting Rect. | 593 // partial pixels in the resulting Rect. |
| 599 Region unoccluded_region_in_target_surface = gfx::ToEnclosingRect( | 594 Region unoccluded_region_in_target_surface = gfx::ToEnclosingRect( |
| 600 MathUtil::MapClippedRect(draw_transform, gfx::RectF(content_rect))); | 595 MathUtil::MapClippedRect(draw_transform, gfx::RectF(content_rect))); |
| 601 // Layers can't clip across surfaces, so count this as internal occlusion. | |
| 602 if (is_clipped) | |
| 603 unoccluded_region_in_target_surface.Intersect(clip_rect_in_target); | |
| 604 unoccluded_region_in_target_surface.Subtract( | 596 unoccluded_region_in_target_surface.Subtract( |
| 605 stack_.back().occlusion_from_inside_target); | 597 stack_.back().occlusion_from_inside_target); |
| 606 gfx::RectF unoccluded_rect_in_target_surface_without_outside_occlusion = | 598 gfx::RectF unoccluded_rect_in_target_surface_without_outside_occlusion = |
| 607 unoccluded_region_in_target_surface.bounds(); | 599 unoccluded_region_in_target_surface.bounds(); |
| 608 unoccluded_region_in_target_surface.Subtract( | 600 unoccluded_region_in_target_surface.Subtract( |
| 609 stack_.back().occlusion_from_outside_target); | 601 stack_.back().occlusion_from_outside_target); |
| 610 | 602 |
| 611 // Treat other clipping as occlusion from outside the surface. | |
| 612 // TODO(danakj): Clip to visibleContentRect? | |
| 613 unoccluded_region_in_target_surface.Intersect( | |
| 614 render_target->render_surface()->content_rect()); | |
| 615 unoccluded_region_in_target_surface.Intersect( | |
| 616 ScreenSpaceClipRectInTargetSurface(render_target->render_surface(), | |
| 617 screen_space_clip_rect_)); | |
| 618 | |
| 619 gfx::RectF unoccluded_rect_in_target_surface = | 603 gfx::RectF unoccluded_rect_in_target_surface = |
| 620 unoccluded_region_in_target_surface.bounds(); | 604 unoccluded_region_in_target_surface.bounds(); |
| 621 gfx::Rect unoccluded_rect = gfx::ToEnclosingRect( | 605 gfx::Rect unoccluded_rect = gfx::ToEnclosingRect( |
| 622 MathUtil::ProjectClippedRect(inverse_draw_transform, | 606 MathUtil::ProjectClippedRect(inverse_draw_transform, |
| 623 unoccluded_rect_in_target_surface)); | 607 unoccluded_rect_in_target_surface)); |
| 624 unoccluded_rect.Intersect(content_rect); | 608 unoccluded_rect.Intersect(content_rect); |
| 625 | 609 |
| 626 return unoccluded_rect; | 610 return unoccluded_rect; |
| 627 } | 611 } |
| 628 | 612 |
| (...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 681 second_last.occlusion_from_inside_target); | 665 second_last.occlusion_from_inside_target); |
| 682 } | 666 } |
| 683 gfx::RectF unoccluded_rect_in_target_surface_without_outside_occlusion = | 667 gfx::RectF unoccluded_rect_in_target_surface_without_outside_occlusion = |
| 684 unoccluded_region_in_target_surface.bounds(); | 668 unoccluded_region_in_target_surface.bounds(); |
| 685 if (has_occlusion) { | 669 if (has_occlusion) { |
| 686 const StackObject& second_last = stack_[stack_.size() - 2]; | 670 const StackObject& second_last = stack_[stack_.size() - 2]; |
| 687 unoccluded_region_in_target_surface.Subtract( | 671 unoccluded_region_in_target_surface.Subtract( |
| 688 second_last.occlusion_from_outside_target); | 672 second_last.occlusion_from_outside_target); |
| 689 } | 673 } |
| 690 | 674 |
| 691 // Treat other clipping as occlusion from outside the target surface. | 675 // Treat other clipping as occlusion from outside the target surface. |
|
danakj
2013/10/03 21:33:15
What is your plan for contributing surfaces next?
alokp
2013/10/03 23:06:31
We should be able to get rid of clipping here as w
| |
| 692 unoccluded_region_in_target_surface.Intersect( | 676 unoccluded_region_in_target_surface.Intersect( |
| 693 contributing_surface_render_target->render_surface()->content_rect()); | 677 contributing_surface_render_target->render_surface()->content_rect()); |
| 694 unoccluded_region_in_target_surface.Intersect( | 678 unoccluded_region_in_target_surface.Intersect( |
| 695 ScreenSpaceClipRectInTargetSurface( | 679 ScreenSpaceClipRectInTargetSurface( |
| 696 contributing_surface_render_target->render_surface(), | 680 contributing_surface_render_target->render_surface(), |
| 697 screen_space_clip_rect_)); | 681 screen_space_clip_rect_)); |
| 698 | 682 |
| 699 gfx::RectF unoccluded_rect_in_target_surface = | 683 gfx::RectF unoccluded_rect_in_target_surface = |
| 700 unoccluded_region_in_target_surface.bounds(); | 684 unoccluded_region_in_target_surface.bounds(); |
| 701 gfx::Rect unoccluded_rect = gfx::ToEnclosingRect( | 685 gfx::Rect unoccluded_rect = gfx::ToEnclosingRect( |
| 702 MathUtil::ProjectClippedRect(inverse_draw_transform, | 686 MathUtil::ProjectClippedRect(inverse_draw_transform, |
| 703 unoccluded_rect_in_target_surface)); | 687 unoccluded_rect_in_target_surface)); |
| 704 unoccluded_rect.Intersect(content_rect); | 688 unoccluded_rect.Intersect(content_rect); |
| 705 | 689 |
| 706 return unoccluded_rect; | 690 return unoccluded_rect; |
| 707 } | 691 } |
| 708 | 692 |
| 709 // Instantiate (and export) templates here for the linker. | 693 // Instantiate (and export) templates here for the linker. |
| 710 template class OcclusionTrackerBase<Layer, RenderSurface>; | 694 template class OcclusionTrackerBase<Layer, RenderSurface>; |
| 711 template class OcclusionTrackerBase<LayerImpl, RenderSurfaceImpl>; | 695 template class OcclusionTrackerBase<LayerImpl, RenderSurfaceImpl>; |
| 712 | 696 |
| 713 } // namespace cc | 697 } // namespace cc |
| OLD | NEW |