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 bool record_metrics_for_frame) |
23 : screen_space_clip_rect_(screen_space_clip_rect), | 23 : overdraw_metrics_(OverdrawMetrics::Create(record_metrics_for_frame)), |
24 overdraw_metrics_(OverdrawMetrics::Create(record_metrics_for_frame)), | |
25 prevent_occlusion_(false), | 24 prevent_occlusion_(false), |
26 occluding_screen_space_rects_(NULL), | 25 occluding_screen_space_rects_(NULL), |
27 non_occluding_screen_space_rects_(NULL) {} | 26 non_occluding_screen_space_rects_(NULL) {} |
28 | 27 |
29 template <typename LayerType, typename RenderSurfaceType> | 28 template <typename LayerType, typename RenderSurfaceType> |
30 OcclusionTrackerBase<LayerType, RenderSurfaceType>::~OcclusionTrackerBase() {} | 29 OcclusionTrackerBase<LayerType, RenderSurfaceType>::~OcclusionTrackerBase() {} |
31 | 30 |
32 template <typename LayerType, typename RenderSurfaceType> | 31 template <typename LayerType, typename RenderSurfaceType> |
33 void OcclusionTrackerBase<LayerType, RenderSurfaceType>::EnterLayer( | 32 void OcclusionTrackerBase<LayerType, RenderSurfaceType>::EnterLayer( |
34 const LayerIteratorPosition<LayerType>& layer_iterator, | 33 const LayerIteratorPosition<LayerType>& layer_iterator, |
(...skipping 17 matching lines...) Expand all Loading... | |
52 MarkOccludedBehindLayer(layer_iterator.current_layer); | 51 MarkOccludedBehindLayer(layer_iterator.current_layer); |
53 // TODO(danakj): This should be done when entering the contributing surface, | 52 // TODO(danakj): This should be done when entering the contributing surface, |
54 // but in a way that the surface's own occlusion won't occlude itself. | 53 // but in a way that the surface's own occlusion won't occlude itself. |
55 else if (layer_iterator.represents_contributing_render_surface) | 54 else if (layer_iterator.represents_contributing_render_surface) |
56 LeaveToRenderTarget(render_target); | 55 LeaveToRenderTarget(render_target); |
57 | 56 |
58 prevent_occlusion_ = false; | 57 prevent_occlusion_ = false; |
59 } | 58 } |
60 | 59 |
61 template <typename RenderSurfaceType> | 60 template <typename RenderSurfaceType> |
62 static gfx::Rect ScreenSpaceClipRectInTargetSurface( | |
63 const RenderSurfaceType* target_surface, gfx::Rect screen_space_clip_rect) { | |
64 gfx::Transform inverse_screen_space_transform( | |
65 gfx::Transform::kSkipInitialization); | |
66 if (!target_surface->screen_space_transform().GetInverse( | |
67 &inverse_screen_space_transform)) | |
68 return target_surface->content_rect(); | |
69 | |
70 return gfx::ToEnclosingRect(MathUtil::ProjectClippedRect( | |
71 inverse_screen_space_transform, screen_space_clip_rect)); | |
72 } | |
73 | |
74 template <typename RenderSurfaceType> | |
75 static Region TransformSurfaceOpaqueRegion(const Region& region, | 61 static Region TransformSurfaceOpaqueRegion(const Region& region, |
76 bool have_clip_rect, | 62 bool have_clip_rect, |
77 gfx::Rect clip_rect_in_new_target, | 63 gfx::Rect clip_rect_in_new_target, |
78 const gfx::Transform& transform) { | 64 const gfx::Transform& transform) { |
79 if (region.IsEmpty()) | 65 if (region.IsEmpty()) |
80 return Region(); | 66 return Region(); |
81 | 67 |
82 // Verify that rects within the |surface| will remain rects in its target | 68 // Verify that rects within the |surface| will remain rects in its target |
83 // surface after applying |transform|. If this is true, then apply |transform| | 69 // surface after applying |transform|. If this is true, then apply |transform| |
84 // to each rect within |region| in order to transform the entire Region. | 70 // to each rect within |region| in order to transform the entire Region. |
(...skipping 344 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
429 Region opaque_contents = layer->VisibleContentOpaqueRegion(); | 415 Region opaque_contents = layer->VisibleContentOpaqueRegion(); |
430 if (opaque_contents.IsEmpty()) | 416 if (opaque_contents.IsEmpty()) |
431 return; | 417 return; |
432 | 418 |
433 DCHECK(layer->visible_content_rect().Contains(opaque_contents.bounds())); | 419 DCHECK(layer->visible_content_rect().Contains(opaque_contents.bounds())); |
434 | 420 |
435 // TODO(danakj): Find a rect interior to each transformed quad. | 421 // TODO(danakj): Find a rect interior to each transformed quad. |
436 if (!layer->draw_transform().Preserves2dAxisAlignment()) | 422 if (!layer->draw_transform().Preserves2dAxisAlignment()) |
437 return; | 423 return; |
438 | 424 |
439 gfx::Rect clip_rect_in_target = ScreenSpaceClipRectInTargetSurface( | |
440 layer->render_target()->render_surface(), screen_space_clip_rect_); | |
441 if (layer->is_clipped()) { | |
442 clip_rect_in_target.Intersect(layer->clip_rect()); | |
443 } else { | |
444 clip_rect_in_target.Intersect( | |
445 layer->render_target()->render_surface()->content_rect()); | |
446 } | |
447 | |
448 for (Region::Iterator opaque_content_rects(opaque_contents); | 425 for (Region::Iterator opaque_content_rects(opaque_contents); |
449 opaque_content_rects.has_rect(); | 426 opaque_content_rects.has_rect(); |
450 opaque_content_rects.next()) { | 427 opaque_content_rects.next()) { |
451 bool clipped; | 428 bool clipped; |
452 gfx::QuadF transformed_quad = MathUtil::MapQuad( | 429 gfx::QuadF transformed_quad = MathUtil::MapQuad( |
453 layer->draw_transform(), | 430 layer->draw_transform(), |
454 gfx::QuadF(opaque_content_rects.rect()), | 431 gfx::QuadF(opaque_content_rects.rect()), |
455 &clipped); | 432 &clipped); |
456 gfx::Rect transformed_rect = | 433 gfx::Rect transformed_rect = |
457 gfx::ToEnclosedRect(transformed_quad.BoundingBox()); | 434 gfx::ToEnclosedRect(transformed_quad.BoundingBox()); |
458 DCHECK(!clipped); // We only map if the transform preserves axis alignment. | 435 DCHECK(!clipped); // We only map if the transform preserves axis alignment. |
459 transformed_rect.Intersect(clip_rect_in_target); | |
danakj
2013/09/10 14:36:37
Not intersecting with the clip rect means you'll m
alokp
2013/09/10 18:15:46
VisibleContentOpaqueRegion is already clipped. It
danakj
2013/09/10 18:21:10
The visible content rect is in content space. So i
alokp
2013/09/10 20:51:27
I do not understand. I am looking at this:
https:/
danakj
2013/09/10 20:54:24
Yes it would, you're right! But if it is not axis-
| |
460 if (transformed_rect.width() < minimum_tracking_size_.width() && | 436 if (transformed_rect.width() < minimum_tracking_size_.width() && |
461 transformed_rect.height() < minimum_tracking_size_.height()) | 437 transformed_rect.height() < minimum_tracking_size_.height()) |
462 continue; | 438 continue; |
463 stack_.back().occlusion_from_inside_target.Union(transformed_rect); | 439 stack_.back().occlusion_from_inside_target.Union(transformed_rect); |
464 | 440 |
465 if (!occluding_screen_space_rects_) | 441 if (!occluding_screen_space_rects_) |
466 continue; | 442 continue; |
467 | 443 |
468 // Save the occluding area in screen space for debug visualization. | 444 // Save the occluding area in screen space for debug visualization. |
469 gfx::QuadF screen_space_quad = MathUtil::MapQuad( | 445 gfx::QuadF screen_space_quad = MathUtil::MapQuad( |
(...skipping 12 matching lines...) Expand all Loading... | |
482 Region non_opaque_contents = | 458 Region non_opaque_contents = |
483 SubtractRegions(gfx::Rect(layer->content_bounds()), opaque_contents); | 459 SubtractRegions(gfx::Rect(layer->content_bounds()), opaque_contents); |
484 for (Region::Iterator non_opaque_content_rects(non_opaque_contents); | 460 for (Region::Iterator non_opaque_content_rects(non_opaque_contents); |
485 non_opaque_content_rects.has_rect(); | 461 non_opaque_content_rects.has_rect(); |
486 non_opaque_content_rects.next()) { | 462 non_opaque_content_rects.next()) { |
487 // We've already checked for clipping in the MapQuad call above, these calls | 463 // We've already checked for clipping in the MapQuad call above, these calls |
488 // should not clip anything further. | 464 // should not clip anything further. |
489 gfx::Rect transformed_rect = gfx::ToEnclosedRect( | 465 gfx::Rect transformed_rect = gfx::ToEnclosedRect( |
490 MathUtil::MapClippedRect(layer->draw_transform(), | 466 MathUtil::MapClippedRect(layer->draw_transform(), |
491 gfx::RectF(non_opaque_content_rects.rect()))); | 467 gfx::RectF(non_opaque_content_rects.rect()))); |
492 transformed_rect.Intersect(clip_rect_in_target); | |
danakj
2013/09/10 14:36:37
same point here
| |
493 if (transformed_rect.IsEmpty()) | 468 if (transformed_rect.IsEmpty()) |
494 continue; | 469 continue; |
495 | 470 |
496 bool clipped; | 471 bool clipped; |
497 gfx::QuadF screen_space_quad = MathUtil::MapQuad( | 472 gfx::QuadF screen_space_quad = MathUtil::MapQuad( |
498 layer->render_target()->render_surface()->screen_space_transform(), | 473 layer->render_target()->render_surface()->screen_space_transform(), |
499 gfx::QuadF(transformed_rect), | 474 gfx::QuadF(transformed_rect), |
500 &clipped); | 475 &clipped); |
501 // TODO(danakj): Store the quad in the debug info instead of the bounding | 476 // TODO(danakj): Store the quad in the debug info instead of the bounding |
502 // box. | 477 // box. |
503 gfx::Rect screen_space_rect = | 478 gfx::Rect screen_space_rect = |
504 gfx::ToEnclosedRect(screen_space_quad.BoundingBox()); | 479 gfx::ToEnclosedRect(screen_space_quad.BoundingBox()); |
505 non_occluding_screen_space_rects_->push_back(screen_space_rect); | 480 non_occluding_screen_space_rects_->push_back(screen_space_rect); |
506 } | 481 } |
507 } | 482 } |
508 | 483 |
509 template <typename LayerType, typename RenderSurfaceType> | 484 template <typename LayerType, typename RenderSurfaceType> |
510 bool OcclusionTrackerBase<LayerType, RenderSurfaceType>::Occluded( | 485 bool OcclusionTrackerBase<LayerType, RenderSurfaceType>::Occluded( |
511 const LayerType* render_target, | 486 const LayerType* render_target, |
512 gfx::Rect content_rect, | 487 gfx::Rect content_rect, |
513 const gfx::Transform& draw_transform, | 488 const gfx::Transform& draw_transform, |
514 bool impl_draw_transform_is_unknown, | 489 bool impl_draw_transform_is_unknown, |
515 bool is_clipped, | |
516 gfx::Rect clip_rect_in_target, | |
517 bool* has_occlusion_from_outside_target_surface) const { | 490 bool* has_occlusion_from_outside_target_surface) const { |
518 if (has_occlusion_from_outside_target_surface) | 491 if (has_occlusion_from_outside_target_surface) |
519 *has_occlusion_from_outside_target_surface = false; | 492 *has_occlusion_from_outside_target_surface = false; |
520 if (prevent_occlusion_) | 493 if (prevent_occlusion_) |
521 return false; | 494 return false; |
522 | 495 |
523 DCHECK(!stack_.empty()); | 496 DCHECK(!stack_.empty()); |
524 if (stack_.empty()) | 497 if (stack_.empty()) |
525 return false; | 498 return false; |
526 if (content_rect.IsEmpty()) | 499 if (content_rect.IsEmpty()) |
527 return true; | 500 return true; |
528 if (impl_draw_transform_is_unknown) | 501 if (impl_draw_transform_is_unknown) |
529 return false; | 502 return false; |
530 | 503 |
531 // For tests with no render target. | 504 // For tests with no render target. |
532 if (!render_target) | 505 if (!render_target) |
533 return false; | 506 return false; |
534 | 507 |
535 DCHECK_EQ(render_target->render_target(), render_target); | 508 DCHECK_EQ(render_target->render_target(), render_target); |
536 DCHECK(render_target->render_surface()); | 509 DCHECK(render_target->render_surface()); |
537 DCHECK_EQ(render_target, stack_.back().target); | 510 DCHECK_EQ(render_target, stack_.back().target); |
538 | 511 |
512 if (stack_.back().occlusion_from_inside_target.IsEmpty() && | |
513 stack_.back().occlusion_from_outside_target.IsEmpty()) { | |
514 return false; | |
515 } | |
516 | |
539 gfx::Transform inverse_draw_transform(gfx::Transform::kSkipInitialization); | 517 gfx::Transform inverse_draw_transform(gfx::Transform::kSkipInitialization); |
540 if (!draw_transform.GetInverse(&inverse_draw_transform)) | 518 if (!draw_transform.GetInverse(&inverse_draw_transform)) |
541 return false; | 519 return false; |
542 | 520 |
543 // Take the ToEnclosingRect at each step, as we want to contain any unoccluded | 521 // Take the ToEnclosingRect at each step, as we want to contain any unoccluded |
544 // partial pixels in the resulting Rect. | 522 // partial pixels in the resulting Rect. |
545 Region unoccluded_region_in_target_surface = gfx::ToEnclosingRect( | 523 Region unoccluded_region_in_target_surface = gfx::ToEnclosingRect( |
546 MathUtil::MapClippedRect(draw_transform, gfx::RectF(content_rect))); | 524 MathUtil::MapClippedRect(draw_transform, gfx::RectF(content_rect))); |
547 // Layers can't clip across surfaces, so count this as internal occlusion. | |
548 if (is_clipped) | |
549 unoccluded_region_in_target_surface.Intersect(clip_rect_in_target); | |
550 unoccluded_region_in_target_surface.Subtract( | 525 unoccluded_region_in_target_surface.Subtract( |
551 stack_.back().occlusion_from_inside_target); | 526 stack_.back().occlusion_from_inside_target); |
552 gfx::RectF unoccluded_rect_in_target_surface_without_outside_occlusion = | 527 gfx::RectF unoccluded_rect_in_target_surface_without_outside_occlusion = |
553 unoccluded_region_in_target_surface.bounds(); | 528 unoccluded_region_in_target_surface.bounds(); |
554 unoccluded_region_in_target_surface.Subtract( | 529 unoccluded_region_in_target_surface.Subtract( |
555 stack_.back().occlusion_from_outside_target); | 530 stack_.back().occlusion_from_outside_target); |
556 | 531 |
557 // Treat other clipping as occlusion from outside the surface. | |
558 // TODO(danakj): Clip to visibleContentRect? | |
559 unoccluded_region_in_target_surface.Intersect( | |
560 render_target->render_surface()->content_rect()); | |
enne (OOO)
2013/09/09 23:37:39
I think you shouldn't remove this line.
alokp
2013/09/10 13:31:44
I think we should. This is also a form of clipping
| |
561 unoccluded_region_in_target_surface.Intersect( | |
562 ScreenSpaceClipRectInTargetSurface(render_target->render_surface(), | |
563 screen_space_clip_rect_)); | |
564 | |
565 gfx::RectF unoccluded_rect_in_target_surface = | 532 gfx::RectF unoccluded_rect_in_target_surface = |
566 unoccluded_region_in_target_surface.bounds(); | 533 unoccluded_region_in_target_surface.bounds(); |
567 | 534 |
568 if (has_occlusion_from_outside_target_surface) { | 535 if (has_occlusion_from_outside_target_surface) { |
569 // Check if the unoccluded rect shrank when applying outside occlusion. | 536 // Check if the unoccluded rect shrank when applying outside occlusion. |
570 *has_occlusion_from_outside_target_surface = !gfx::SubtractRects( | 537 *has_occlusion_from_outside_target_surface = !gfx::SubtractRects( |
danakj
2013/09/10 14:36:37
Have you thought through how we can preserve this
alokp
2013/09/10 18:15:46
Sorry I have not looked at occlusion-from-outside
danakj
2013/09/10 18:21:10
It is different. This bit is false if nothing affe
| |
571 unoccluded_rect_in_target_surface_without_outside_occlusion, | 538 unoccluded_rect_in_target_surface_without_outside_occlusion, |
572 unoccluded_rect_in_target_surface).IsEmpty(); | 539 unoccluded_rect_in_target_surface).IsEmpty(); |
573 } | 540 } |
574 | 541 |
575 return unoccluded_rect_in_target_surface.IsEmpty(); | 542 return unoccluded_rect_in_target_surface.IsEmpty(); |
576 } | 543 } |
577 | 544 |
578 template <typename LayerType, typename RenderSurfaceType> | 545 template <typename LayerType, typename RenderSurfaceType> |
579 gfx::Rect OcclusionTrackerBase<LayerType, RenderSurfaceType>:: | 546 gfx::Rect OcclusionTrackerBase<LayerType, RenderSurfaceType>:: |
580 UnoccludedContentRect( | 547 UnoccludedContentRect( |
581 const LayerType* render_target, | 548 const LayerType* render_target, |
582 gfx::Rect content_rect, | 549 gfx::Rect content_rect, |
583 const gfx::Transform& draw_transform, | 550 const gfx::Transform& draw_transform, |
584 bool impl_draw_transform_is_unknown, | 551 bool impl_draw_transform_is_unknown, |
585 bool is_clipped, | |
586 gfx::Rect clip_rect_in_target, | |
587 bool* has_occlusion_from_outside_target_surface) const { | 552 bool* has_occlusion_from_outside_target_surface) const { |
588 if (has_occlusion_from_outside_target_surface) | 553 if (has_occlusion_from_outside_target_surface) |
589 *has_occlusion_from_outside_target_surface = false; | 554 *has_occlusion_from_outside_target_surface = false; |
590 if (prevent_occlusion_) | 555 if (prevent_occlusion_) |
591 return content_rect; | 556 return content_rect; |
592 | 557 |
593 DCHECK(!stack_.empty()); | 558 DCHECK(!stack_.empty()); |
594 if (stack_.empty()) | 559 if (stack_.empty()) |
595 return content_rect; | 560 return content_rect; |
596 if (content_rect.IsEmpty()) | 561 if (content_rect.IsEmpty()) |
597 return content_rect; | 562 return content_rect; |
598 if (impl_draw_transform_is_unknown) | 563 if (impl_draw_transform_is_unknown) |
599 return content_rect; | 564 return content_rect; |
600 | 565 |
601 // For tests with no render target. | 566 // For tests with no render target. |
602 if (!render_target) | 567 if (!render_target) |
603 return content_rect; | 568 return content_rect; |
604 | 569 |
605 DCHECK_EQ(render_target->render_target(), render_target); | 570 DCHECK_EQ(render_target->render_target(), render_target); |
606 DCHECK(render_target->render_surface()); | 571 DCHECK(render_target->render_surface()); |
607 DCHECK_EQ(render_target, stack_.back().target); | 572 DCHECK_EQ(render_target, stack_.back().target); |
608 | 573 |
574 if (stack_.back().occlusion_from_inside_target.IsEmpty() && | |
575 stack_.back().occlusion_from_outside_target.IsEmpty()) { | |
576 return content_rect; | |
577 } | |
578 | |
609 gfx::Transform inverse_draw_transform(gfx::Transform::kSkipInitialization); | 579 gfx::Transform inverse_draw_transform(gfx::Transform::kSkipInitialization); |
610 if (!draw_transform.GetInverse(&inverse_draw_transform)) | 580 if (!draw_transform.GetInverse(&inverse_draw_transform)) |
611 return content_rect; | 581 return content_rect; |
612 | 582 |
613 // Take the ToEnclosingRect at each step, as we want to contain any unoccluded | 583 // Take the ToEnclosingRect at each step, as we want to contain any unoccluded |
614 // partial pixels in the resulting Rect. | 584 // partial pixels in the resulting Rect. |
615 Region unoccluded_region_in_target_surface = gfx::ToEnclosingRect( | 585 Region unoccluded_region_in_target_surface = gfx::ToEnclosingRect( |
616 MathUtil::MapClippedRect(draw_transform, gfx::RectF(content_rect))); | 586 MathUtil::MapClippedRect(draw_transform, gfx::RectF(content_rect))); |
617 // Layers can't clip across surfaces, so count this as internal occlusion. | |
618 if (is_clipped) | |
619 unoccluded_region_in_target_surface.Intersect(clip_rect_in_target); | |
620 unoccluded_region_in_target_surface.Subtract( | 587 unoccluded_region_in_target_surface.Subtract( |
621 stack_.back().occlusion_from_inside_target); | 588 stack_.back().occlusion_from_inside_target); |
622 gfx::RectF unoccluded_rect_in_target_surface_without_outside_occlusion = | 589 gfx::RectF unoccluded_rect_in_target_surface_without_outside_occlusion = |
623 unoccluded_region_in_target_surface.bounds(); | 590 unoccluded_region_in_target_surface.bounds(); |
624 unoccluded_region_in_target_surface.Subtract( | 591 unoccluded_region_in_target_surface.Subtract( |
625 stack_.back().occlusion_from_outside_target); | 592 stack_.back().occlusion_from_outside_target); |
626 | 593 |
627 // Treat other clipping as occlusion from outside the surface. | |
628 // TODO(danakj): Clip to visibleContentRect? | |
629 unoccluded_region_in_target_surface.Intersect( | |
630 render_target->render_surface()->content_rect()); | |
enne (OOO)
2013/09/09 23:37:39
Same here.
| |
631 unoccluded_region_in_target_surface.Intersect( | |
632 ScreenSpaceClipRectInTargetSurface(render_target->render_surface(), | |
633 screen_space_clip_rect_)); | |
634 | |
635 gfx::RectF unoccluded_rect_in_target_surface = | 594 gfx::RectF unoccluded_rect_in_target_surface = |
636 unoccluded_region_in_target_surface.bounds(); | 595 unoccluded_region_in_target_surface.bounds(); |
637 gfx::Rect unoccluded_rect = gfx::ToEnclosingRect( | 596 gfx::Rect unoccluded_rect = gfx::ToEnclosingRect( |
638 MathUtil::ProjectClippedRect(inverse_draw_transform, | 597 MathUtil::ProjectClippedRect(inverse_draw_transform, |
639 unoccluded_rect_in_target_surface)); | 598 unoccluded_rect_in_target_surface)); |
640 unoccluded_rect.Intersect(content_rect); | 599 unoccluded_rect.Intersect(content_rect); |
641 | 600 |
642 if (has_occlusion_from_outside_target_surface) { | 601 if (has_occlusion_from_outside_target_surface) { |
643 // Check if the unoccluded rect shrank when applying outside occlusion. | 602 // Check if the unoccluded rect shrank when applying outside occlusion. |
644 *has_occlusion_from_outside_target_surface = !gfx::SubtractRects( | 603 *has_occlusion_from_outside_target_surface = !gfx::SubtractRects( |
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
693 // surface, so only things outside the surface can occlude it. That occlusion | 652 // surface, so only things outside the surface can occlude it. That occlusion |
694 // is found just below the top of the stack (if it exists). | 653 // is found just below the top of the stack (if it exists). |
695 bool has_occlusion = stack_.size() > 1; | 654 bool has_occlusion = stack_.size() > 1; |
696 | 655 |
697 // Take the ToEnclosingRect at each step, as we want to contain any unoccluded | 656 // Take the ToEnclosingRect at each step, as we want to contain any unoccluded |
698 // partial pixels in the resulting Rect. | 657 // partial pixels in the resulting Rect. |
699 Region unoccluded_region_in_target_surface = gfx::ToEnclosingRect( | 658 Region unoccluded_region_in_target_surface = gfx::ToEnclosingRect( |
700 MathUtil::MapClippedRect(draw_transform, gfx::RectF(content_rect))); | 659 MathUtil::MapClippedRect(draw_transform, gfx::RectF(content_rect))); |
701 // Layers can't clip across surfaces, so count this as internal occlusion. | 660 // Layers can't clip across surfaces, so count this as internal occlusion. |
702 if (surface->is_clipped()) | 661 if (surface->is_clipped()) |
703 unoccluded_region_in_target_surface.Intersect(surface->clip_rect()); | 662 unoccluded_region_in_target_surface.Intersect(surface->clip_rect()); |
danakj
2013/09/10 14:36:37
This too?
alokp
2013/09/10 18:15:46
I have not looked at optimizing surface-rects yet.
danakj
2013/09/10 18:21:10
I think you'll need to handle more than just tile
alokp
2013/09/10 20:51:27
OK. I will look at them once we resolve all the la
| |
704 if (has_occlusion) { | 663 if (has_occlusion) { |
705 const StackObject& second_last = stack_[stack_.size() - 2]; | 664 const StackObject& second_last = stack_[stack_.size() - 2]; |
706 unoccluded_region_in_target_surface.Subtract( | 665 unoccluded_region_in_target_surface.Subtract( |
707 second_last.occlusion_from_inside_target); | 666 second_last.occlusion_from_inside_target); |
708 } | 667 } |
709 gfx::RectF unoccluded_rect_in_target_surface_without_outside_occlusion = | 668 gfx::RectF unoccluded_rect_in_target_surface_without_outside_occlusion = |
710 unoccluded_region_in_target_surface.bounds(); | 669 unoccluded_region_in_target_surface.bounds(); |
711 if (has_occlusion) { | 670 if (has_occlusion) { |
712 const StackObject& second_last = stack_[stack_.size() - 2]; | 671 const StackObject& second_last = stack_[stack_.size() - 2]; |
713 unoccluded_region_in_target_surface.Subtract( | 672 unoccluded_region_in_target_surface.Subtract( |
714 second_last.occlusion_from_outside_target); | 673 second_last.occlusion_from_outside_target); |
715 } | 674 } |
716 | 675 |
717 // Treat other clipping as occlusion from outside the target surface. | 676 // Treat other clipping as occlusion from outside the target surface. |
718 unoccluded_region_in_target_surface.Intersect( | 677 unoccluded_region_in_target_surface.Intersect( |
719 contributing_surface_render_target->render_surface()->content_rect()); | 678 contributing_surface_render_target->render_surface()->content_rect()); |
danakj
2013/09/10 14:36:37
Why not this?
alokp
2013/09/10 18:15:46
I am planning to work on surface-rects in a separa
| |
720 unoccluded_region_in_target_surface.Intersect( | |
721 ScreenSpaceClipRectInTargetSurface( | |
722 contributing_surface_render_target->render_surface(), | |
723 screen_space_clip_rect_)); | |
724 | 679 |
725 gfx::RectF unoccluded_rect_in_target_surface = | 680 gfx::RectF unoccluded_rect_in_target_surface = |
726 unoccluded_region_in_target_surface.bounds(); | 681 unoccluded_region_in_target_surface.bounds(); |
727 gfx::Rect unoccluded_rect = gfx::ToEnclosingRect( | 682 gfx::Rect unoccluded_rect = gfx::ToEnclosingRect( |
728 MathUtil::ProjectClippedRect(inverse_draw_transform, | 683 MathUtil::ProjectClippedRect(inverse_draw_transform, |
729 unoccluded_rect_in_target_surface)); | 684 unoccluded_rect_in_target_surface)); |
730 unoccluded_rect.Intersect(content_rect); | 685 unoccluded_rect.Intersect(content_rect); |
731 | 686 |
732 if (has_occlusion_from_outside_target_surface) { | 687 if (has_occlusion_from_outside_target_surface) { |
733 // Check if the unoccluded rect shrank when applying outside occlusion. | 688 // Check if the unoccluded rect shrank when applying outside occlusion. |
734 *has_occlusion_from_outside_target_surface = !gfx::SubtractRects( | 689 *has_occlusion_from_outside_target_surface = !gfx::SubtractRects( |
735 unoccluded_rect_in_target_surface_without_outside_occlusion, | 690 unoccluded_rect_in_target_surface_without_outside_occlusion, |
736 unoccluded_rect_in_target_surface).IsEmpty(); | 691 unoccluded_rect_in_target_surface).IsEmpty(); |
737 } | 692 } |
738 | 693 |
739 return unoccluded_rect; | 694 return unoccluded_rect; |
740 } | 695 } |
741 | 696 |
742 // Instantiate (and export) templates here for the linker. | 697 // Instantiate (and export) templates here for the linker. |
743 template class OcclusionTrackerBase<Layer, RenderSurface>; | 698 template class OcclusionTrackerBase<Layer, RenderSurface>; |
744 template class OcclusionTrackerBase<LayerImpl, RenderSurfaceImpl>; | 699 template class OcclusionTrackerBase<LayerImpl, RenderSurfaceImpl>; |
745 | 700 |
746 } // namespace cc | 701 } // namespace cc |
OLD | NEW |