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 75 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
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 |