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

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

Issue 205443002: Do not clip inside OcclusionTracker: Contributing Surfaces Edition. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: occlusion-surface: Created 6 years, 9 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 | Annotate | Revision Log
OLDNEW
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/layers/layer.h" 10 #include "cc/layers/layer.h"
(...skipping 317 matching lines...) Expand 10 before | Expand all | Expand 10 after
328 TransformSurfaceOpaqueRegion<typename LayerType::RenderSurfaceType>( 328 TransformSurfaceOpaqueRegion<typename LayerType::RenderSurfaceType>(
329 stack_[last_index].occlusion_from_outside_target, 329 stack_[last_index].occlusion_from_outside_target,
330 false, 330 false,
331 gfx::Rect(), 331 gfx::Rect(),
332 old_surface->draw_transform()); 332 old_surface->draw_transform());
333 333
334 gfx::Rect unoccluded_surface_rect; 334 gfx::Rect unoccluded_surface_rect;
335 gfx::Rect unoccluded_replica_rect; 335 gfx::Rect unoccluded_replica_rect;
336 if (old_target->background_filters().HasFilterThatMovesPixels()) { 336 if (old_target->background_filters().HasFilterThatMovesPixels()) {
337 unoccluded_surface_rect = UnoccludedContributingSurfaceContentRect( 337 unoccluded_surface_rect = UnoccludedContributingSurfaceContentRect(
338 old_target, false, old_surface->content_rect()); 338 old_target, old_surface->content_rect(), old_surface->draw_transform());
339 if (old_target->has_replica()) { 339 if (old_target->has_replica()) {
340 unoccluded_replica_rect = UnoccludedContributingSurfaceContentRect( 340 unoccluded_replica_rect = UnoccludedContributingSurfaceContentRect(
341 old_target, true, old_surface->content_rect()); 341 old_target,
342 old_surface->content_rect(),
343 old_surface->replica_draw_transform());
342 } 344 }
343 } 345 }
344 346
345 if (surface_will_be_at_top_after_pop) { 347 if (surface_will_be_at_top_after_pop) {
346 // Merge the top of the stack down. 348 // Merge the top of the stack down.
347 stack_[last_index - 1].occlusion_from_inside_target.Union( 349 stack_[last_index - 1].occlusion_from_inside_target.Union(
348 old_occlusion_from_inside_target_in_new_target); 350 old_occlusion_from_inside_target_in_new_target);
349 // TODO(danakj): Strictly this should subtract the inside target occlusion 351 // TODO(danakj): Strictly this should subtract the inside target occlusion
350 // before union. 352 // before union.
351 if (new_target->parent()) { 353 if (new_target->parent()) {
(...skipping 232 matching lines...) Expand 10 before | Expand all | Expand 10 after
584 gfx::Rect unoccluded_rect = MathUtil::ProjectEnclosingClippedRect( 586 gfx::Rect unoccluded_rect = MathUtil::ProjectEnclosingClippedRect(
585 inverse_draw_transform, unoccluded_rect_in_target_surface); 587 inverse_draw_transform, unoccluded_rect_in_target_surface);
586 unoccluded_rect.Intersect(content_rect); 588 unoccluded_rect.Intersect(content_rect);
587 589
588 return unoccluded_rect; 590 return unoccluded_rect;
589 } 591 }
590 592
591 template <typename LayerType> 593 template <typename LayerType>
592 gfx::Rect OcclusionTracker<LayerType>::UnoccludedContributingSurfaceContentRect( 594 gfx::Rect OcclusionTracker<LayerType>::UnoccludedContributingSurfaceContentRect(
593 const LayerType* layer, 595 const LayerType* layer,
594 bool for_replica, 596 const gfx::Rect& content_rect,
595 const gfx::Rect& content_rect) const { 597 const gfx::Transform& draw_transform) const {
596 DCHECK(!stack_.empty()); 598 DCHECK(!stack_.empty());
597 // The layer is a contributing render_target so it should have a surface. 599 // The layer is a contributing render_target so it should have a surface.
598 DCHECK(layer->render_surface()); 600 DCHECK(layer->render_surface());
599 // The layer is a contributing render_target so its target should be itself. 601 // The layer is a contributing render_target so its target should be itself.
600 DCHECK_EQ(layer->render_target(), layer); 602 DCHECK_EQ(layer->render_target(), layer);
601 // The layer should not be the root, else what is is contributing to? 603 // The layer should not be the root, else what is is contributing to?
602 DCHECK(layer->parent()); 604 DCHECK(layer->parent());
603 // This should be called while the layer is still considered the current 605 // This should be called while the layer is still considered the current
604 // target in the occlusion tracker. 606 // target in the occlusion tracker.
605 DCHECK_EQ(layer, stack_.back().target); 607 DCHECK_EQ(layer, stack_.back().target);
606 608
607 if (content_rect.IsEmpty()) 609 if (content_rect.IsEmpty())
608 return content_rect; 610 return content_rect;
609 611
610 const typename LayerType::RenderSurfaceType* surface =
611 layer->render_surface();
612 const LayerType* contributing_surface_render_target =
613 layer->parent()->render_target();
614
615 if (!SurfaceTransformsToTargetKnown(surface))
616 return content_rect;
617
618 gfx::Transform draw_transform =
619 for_replica ? surface->replica_draw_transform()
620 : surface->draw_transform();
621 gfx::Transform inverse_draw_transform(gfx::Transform::kSkipInitialization);
622 if (!draw_transform.GetInverse(&inverse_draw_transform))
623 return content_rect;
624
625 // A contributing surface doesn't get occluded by things inside its own 612 // A contributing surface doesn't get occluded by things inside its own
626 // surface, so only things outside the surface can occlude it. That occlusion 613 // surface, so only things outside the surface can occlude it. That occlusion
627 // is found just below the top of the stack (if it exists). 614 // is found just below the top of the stack (if it exists).
628 bool has_occlusion = stack_.size() > 1; 615 bool has_occlusion = stack_.size() > 1;
616 if (!has_occlusion)
617 return content_rect;
618
619 const StackObject& second_last = stack_[stack_.size() - 2];
620
621 if (second_last.occlusion_from_inside_target.IsEmpty() &&
622 second_last.occlusion_from_outside_target.IsEmpty())
623 return content_rect;
624
625 gfx::Transform inverse_draw_transform(gfx::Transform::kSkipInitialization);
626 if (!draw_transform.GetInverse(&inverse_draw_transform))
627 return content_rect;
629 628
630 // Take the ToEnclosingRect at each step, as we want to contain any unoccluded 629 // Take the ToEnclosingRect at each step, as we want to contain any unoccluded
631 // partial pixels in the resulting Rect. 630 // partial pixels in the resulting Rect.
632 Region unoccluded_region_in_target_surface = 631 Region unoccluded_region_in_target_surface =
633 MathUtil::MapEnclosingClippedRect(draw_transform, content_rect); 632 MathUtil::MapEnclosingClippedRect(draw_transform, content_rect);
634 // Layers can't clip across surfaces, so count this as internal occlusion. 633 unoccluded_region_in_target_surface.Subtract(
635 if (surface->is_clipped()) 634 second_last.occlusion_from_inside_target);
636 unoccluded_region_in_target_surface.Intersect(surface->clip_rect()); 635 unoccluded_region_in_target_surface.Subtract(
637 if (has_occlusion) { 636 second_last.occlusion_from_outside_target);
638 const StackObject& second_last = stack_[stack_.size() - 2];
639 unoccluded_region_in_target_surface.Subtract(
640 second_last.occlusion_from_inside_target);
641 unoccluded_region_in_target_surface.Subtract(
642 second_last.occlusion_from_outside_target);
643 }
644
645 // Treat other clipping as occlusion from outside the target surface.
646 unoccluded_region_in_target_surface.Intersect(
647 contributing_surface_render_target->render_surface()->content_rect());
648 unoccluded_region_in_target_surface.Intersect(
649 ScreenSpaceClipRectInTargetSurface(
650 contributing_surface_render_target->render_surface(),
651 screen_space_clip_rect_));
652 637
653 gfx::Rect unoccluded_rect_in_target_surface = 638 gfx::Rect unoccluded_rect_in_target_surface =
654 unoccluded_region_in_target_surface.bounds(); 639 unoccluded_region_in_target_surface.bounds();
655 gfx::Rect unoccluded_rect = MathUtil::ProjectEnclosingClippedRect( 640 gfx::Rect unoccluded_rect = MathUtil::ProjectEnclosingClippedRect(
656 inverse_draw_transform, unoccluded_rect_in_target_surface); 641 inverse_draw_transform, unoccluded_rect_in_target_surface);
657 unoccluded_rect.Intersect(content_rect); 642 unoccluded_rect.Intersect(content_rect);
658 643
659 return unoccluded_rect; 644 return unoccluded_rect;
660 } 645 }
661 646
662 // Instantiate (and export) templates here for the linker. 647 // Instantiate (and export) templates here for the linker.
663 template class OcclusionTracker<Layer>; 648 template class OcclusionTracker<Layer>;
664 template class OcclusionTracker<LayerImpl>; 649 template class OcclusionTracker<LayerImpl>;
665 650
666 } // namespace cc 651 } // namespace cc
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698