OLD | NEW |
1 // Copyright 2011 The Chromium Authors. All rights reserved. | 1 // Copyright 2011 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/layer_tree_host_common.h" | 5 #include "cc/layer_tree_host_common.h" |
6 | 6 |
7 #include <algorithm> | 7 #include <algorithm> |
8 | 8 |
9 #include "cc/layer.h" | 9 #include "cc/layer.h" |
10 #include "cc/layer_impl.h" | 10 #include "cc/layer_impl.h" |
(...skipping 468 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
479 // M[replica2root] = M[surface2root] * Tr[replica->position()] * Tr[r
eplica] * Tr[origin2anchor].inverse() | 479 // M[replica2root] = M[surface2root] * Tr[replica->position()] * Tr[r
eplica] * Tr[origin2anchor].inverse() |
480 // | 480 // |
481 | 481 |
482 // If we early-exit anywhere in this function, the drawableContentRect of th
is subtree should be considered empty. | 482 // If we early-exit anywhere in this function, the drawableContentRect of th
is subtree should be considered empty. |
483 drawableContentRectOfSubtree = gfx::Rect(); | 483 drawableContentRectOfSubtree = gfx::Rect(); |
484 | 484 |
485 // The root layer cannot skip calcDrawTransforms. | 485 // The root layer cannot skip calcDrawTransforms. |
486 if (!isRootLayer(layer) && subtreeShouldBeSkipped(layer)) | 486 if (!isRootLayer(layer) && subtreeShouldBeSkipped(layer)) |
487 return; | 487 return; |
488 | 488 |
| 489 // As this function proceeds, these are the properties for each layer that |
| 490 // actually get computed. To avoid unnecessary copies (particularly for |
| 491 // matrices), we do computations directly on these values when possible. |
| 492 DrawProperties<LayerType>& layerDrawProperties = layer->drawProperties(); |
| 493 |
489 gfx::Rect clipRectForSubtree; | 494 gfx::Rect clipRectForSubtree; |
490 bool subtreeShouldBeClipped = false; | 495 bool subtreeShouldBeClipped = false; |
491 | 496 |
492 float drawOpacity = layer->opacity(); | 497 float accumulatedDrawOpacity = layer->opacity(); |
493 bool drawOpacityIsAnimating = layer->opacityIsAnimating(); | 498 bool drawOpacityIsAnimating = layer->opacityIsAnimating(); |
494 if (layer->parent()) { | 499 if (layer->parent()) { |
495 drawOpacity *= layer->parent()->drawOpacity(); | 500 accumulatedDrawOpacity *= layer->parent()->drawOpacity(); |
496 drawOpacityIsAnimating |= layer->parent()->drawOpacityIsAnimating(); | 501 drawOpacityIsAnimating |= layer->parent()->drawOpacityIsAnimating(); |
497 } | 502 } |
498 | 503 |
499 bool animatingTransformToTarget = layer->transformIsAnimating(); | 504 bool animatingTransformToTarget = layer->transformIsAnimating(); |
500 bool animatingTransformToScreen = animatingTransformToTarget; | 505 bool animatingTransformToScreen = animatingTransformToTarget; |
501 if (layer->parent()) { | 506 if (layer->parent()) { |
502 animatingTransformToTarget |= layer->parent()->drawTransformIsAnimating(
); | 507 animatingTransformToTarget |= layer->parent()->drawTransformIsAnimating(
); |
503 animatingTransformToScreen |= layer->parent()->screenSpaceTransformIsAni
mating(); | 508 animatingTransformToScreen |= layer->parent()->screenSpaceTransformIsAni
mating(); |
504 } | 509 } |
505 | 510 |
(...skipping 15 matching lines...) Expand all Loading... |
521 | 526 |
522 if (layer->fixedToContainerLayer()) { | 527 if (layer->fixedToContainerLayer()) { |
523 // Special case: this layer is a composited fixed-position layer; we nee
d to | 528 // Special case: this layer is a composited fixed-position layer; we nee
d to |
524 // explicitly compensate for all ancestors' nonzero scrollDeltas to keep
this layer | 529 // explicitly compensate for all ancestors' nonzero scrollDeltas to keep
this layer |
525 // fixed correctly. | 530 // fixed correctly. |
526 combinedTransform = currentScrollCompensationMatrix * combinedTransform; | 531 combinedTransform = currentScrollCompensationMatrix * combinedTransform; |
527 } | 532 } |
528 | 533 |
529 // The drawTransform that gets computed below is effectively the layer's dra
wTransform, unless | 534 // The drawTransform that gets computed below is effectively the layer's dra
wTransform, unless |
530 // the layer itself creates a renderSurface. In that case, the renderSurface
re-parents the transforms. | 535 // the layer itself creates a renderSurface. In that case, the renderSurface
re-parents the transforms. |
531 gfx::Transform drawTransform = combinedTransform; | 536 layerDrawProperties.drawTransform = combinedTransform; |
532 // M[draw] = M[parent] * LT * S[layer2content] | 537 // M[draw] = M[parent] * LT * S[layer2content] |
533 drawTransform.Scale(1.0 / layer->contentsScaleX(), 1.0 / layer->contentsScal
eY()); | 538 layerDrawProperties.drawTransform.Scale(1.0 / layer->contentsScaleX(), 1.0 /
layer->contentsScaleY()); |
534 | 539 |
535 // layerScreenSpaceTransform represents the transform between root layer's "
screen space" and local content space. | 540 // layerScreenSpaceTransform represents the transform between root layer's "
screen space" and local content space. |
536 gfx::Transform layerScreenSpaceTransform = fullHierarchyMatrix; | 541 layerDrawProperties.screenSpaceTransform = fullHierarchyMatrix; |
537 if (!layer->preserves3D()) | 542 if (!layer->preserves3D()) |
538 MathUtil::flattenTransformTo2d(layerScreenSpaceTransform); | 543 MathUtil::flattenTransformTo2d(layerDrawProperties.screenSpaceTransform)
; |
539 layerScreenSpaceTransform.PreconcatTransform(drawTransform); | 544 layerDrawProperties.screenSpaceTransform.PreconcatTransform(layerDrawPropert
ies.drawTransform); |
540 layer->setScreenSpaceTransform(layerScreenSpaceTransform); | |
541 | 545 |
542 gfx::RectF contentRect(gfx::PointF(), layer->contentBounds()); | 546 gfx::RectF contentRect(gfx::PointF(), layer->contentBounds()); |
543 | 547 |
544 // fullHierarchyMatrix is the matrix that transforms objects between screen
space (except projection matrix) and the most recent RenderSurfaceImpl's space. | 548 // fullHierarchyMatrix is the matrix that transforms objects between screen
space (except projection matrix) and the most recent RenderSurfaceImpl's space. |
545 // nextHierarchyMatrix will only change if this layer uses a new RenderSurfa
ceImpl, otherwise remains the same. | 549 // nextHierarchyMatrix will only change if this layer uses a new RenderSurfa
ceImpl, otherwise remains the same. |
546 gfx::Transform nextHierarchyMatrix = fullHierarchyMatrix; | 550 gfx::Transform nextHierarchyMatrix = fullHierarchyMatrix; |
547 gfx::Transform sublayerMatrix; | 551 gfx::Transform sublayerMatrix; |
548 | 552 |
549 gfx::Vector2dF renderSurfaceSublayerScale = MathUtil::computeTransform2dScal
eComponents(combinedTransform); | 553 gfx::Vector2dF renderSurfaceSublayerScale = MathUtil::computeTransform2dScal
eComponents(combinedTransform); |
550 | 554 |
(...skipping 11 matching lines...) Expand all Loading... |
562 // The owning layer's draw transform has a scale from content to layer | 566 // The owning layer's draw transform has a scale from content to layer |
563 // space which do not want; so here we use the combinedTransform | 567 // space which do not want; so here we use the combinedTransform |
564 // instead of the drawTransform. However, we do need to add a different | 568 // instead of the drawTransform. However, we do need to add a different |
565 // scale factor that accounts for the surface's pixel dimensions. | 569 // scale factor that accounts for the surface's pixel dimensions. |
566 combinedTransform.Scale(1 / renderSurfaceSublayerScale.x(), 1 / renderSu
rfaceSublayerScale.y()); | 570 combinedTransform.Scale(1 / renderSurfaceSublayerScale.x(), 1 / renderSu
rfaceSublayerScale.y()); |
567 renderSurface->setDrawTransform(combinedTransform); | 571 renderSurface->setDrawTransform(combinedTransform); |
568 | 572 |
569 // The owning layer's transform was re-parented by the surface, so the l
ayer's new drawTransform | 573 // The owning layer's transform was re-parented by the surface, so the l
ayer's new drawTransform |
570 // only needs to scale the layer to surface space. | 574 // only needs to scale the layer to surface space. |
571 gfx::Transform layerDrawTransform; | 575 gfx::Transform layerDrawTransform; |
572 layerDrawTransform.Scale(renderSurfaceSublayerScale.x() / layer->content
sScaleX(), renderSurfaceSublayerScale.y() / layer->contentsScaleY()); | 576 layerDrawProperties.drawTransform.MakeIdentity(); |
573 layer->setDrawTransform(layerDrawTransform); | 577 layerDrawProperties.drawTransform.Scale(renderSurfaceSublayerScale.x() /
layer->contentsScaleX(), renderSurfaceSublayerScale.y() / layer->contentsScaleY
()); |
574 | 578 |
575 // Inside the surface's subtree, we scale everything to the owning layer
's scale. | 579 // Inside the surface's subtree, we scale everything to the owning layer
's scale. |
576 // The sublayer matrix transforms centered layer rects into target | 580 // The sublayer matrix transforms centered layer rects into target |
577 // surface content space. | 581 // surface content space. |
578 DCHECK(sublayerMatrix.IsIdentity()); | 582 DCHECK(sublayerMatrix.IsIdentity()); |
579 sublayerMatrix.Scale(renderSurfaceSublayerScale.x(), renderSurfaceSublay
erScale.y()); | 583 sublayerMatrix.Scale(renderSurfaceSublayerScale.x(), renderSurfaceSublay
erScale.y()); |
580 | 584 |
581 // The opacity value is moved from the layer to its surface, so that the
entire subtree properly inherits opacity. | 585 // The opacity value is moved from the layer to its surface, so that the
entire subtree properly inherits opacity. |
582 renderSurface->setDrawOpacity(drawOpacity); | 586 renderSurface->setDrawOpacity(accumulatedDrawOpacity); |
583 renderSurface->setDrawOpacityIsAnimating(drawOpacityIsAnimating); | 587 renderSurface->setDrawOpacityIsAnimating(drawOpacityIsAnimating); |
584 layer->setDrawOpacity(1); | 588 layerDrawProperties.drawOpacity = 1; |
585 layer->setDrawOpacityIsAnimating(false); | 589 layerDrawProperties.drawOpacityIsAnimating = false; |
586 | 590 |
587 renderSurface->setTargetSurfaceTransformsAreAnimating(animatingTransform
ToTarget); | 591 renderSurface->setTargetSurfaceTransformsAreAnimating(animatingTransform
ToTarget); |
588 renderSurface->setScreenSpaceTransformsAreAnimating(animatingTransformTo
Screen); | 592 renderSurface->setScreenSpaceTransformsAreAnimating(animatingTransformTo
Screen); |
589 animatingTransformToTarget = false; | 593 layerDrawProperties.drawTransformIsAnimating = false; |
590 layer->setDrawTransformIsAnimating(animatingTransformToTarget); | 594 layerDrawProperties.screenSpaceTransformIsAnimating = animatingTransform
ToScreen; |
591 layer->setScreenSpaceTransformIsAnimating(animatingTransformToScreen); | |
592 | 595 |
593 // Update the aggregate hierarchy matrix to include the transform of the | 596 // Update the aggregate hierarchy matrix to include the transform of the |
594 // newly created RenderSurfaceImpl. | 597 // newly created RenderSurfaceImpl. |
595 nextHierarchyMatrix.PreconcatTransform(renderSurface->drawTransform()); | 598 nextHierarchyMatrix.PreconcatTransform(renderSurface->drawTransform()); |
596 | 599 |
597 // The new renderSurface here will correctly clip the entire subtree. So
, we do | 600 // The new renderSurface here will correctly clip the entire subtree. So
, we do |
598 // not need to continue propagating the clipping state further down the
tree. This | 601 // not need to continue propagating the clipping state further down the
tree. This |
599 // way, we can avoid transforming clipRects from ancestor target surface
space to | 602 // way, we can avoid transforming clipRects from ancestor target surface
space to |
600 // current target surface space that could cause more w < 0 headaches. | 603 // current target surface space that could cause more w < 0 headaches. |
601 subtreeShouldBeClipped = false; | 604 subtreeShouldBeClipped = false; |
602 | 605 |
603 if (layer->maskLayer()) { | 606 if (layer->maskLayer()) { |
604 layer->maskLayer()->setRenderTarget(layer); | 607 DrawProperties<LayerType>& maskLayerDrawProperties = layer->maskLaye
r()->drawProperties(); |
605 layer->maskLayer()->setVisibleContentRect(gfx::Rect(gfx::Point(), la
yer->contentBounds())); | 608 maskLayerDrawProperties.renderTarget = layer; |
| 609 maskLayerDrawProperties.visibleContentRect = gfx::Rect(gfx::Point(),
layer->contentBounds()); |
606 } | 610 } |
607 | 611 |
608 if (layer->replicaLayer() && layer->replicaLayer()->maskLayer()) { | 612 if (layer->replicaLayer() && layer->replicaLayer()->maskLayer()) { |
609 layer->replicaLayer()->maskLayer()->setRenderTarget(layer); | 613 DrawProperties<LayerType>& replicaMaskDrawProperties = layer->replic
aLayer()->maskLayer()->drawProperties(); |
610 layer->replicaLayer()->maskLayer()->setVisibleContentRect(gfx::Rect(
gfx::Point(), layer->contentBounds())); | 614 replicaMaskDrawProperties.renderTarget = layer; |
| 615 replicaMaskDrawProperties.visibleContentRect = gfx::Rect(gfx::Point(
), layer->contentBounds()); |
611 } | 616 } |
612 | 617 |
613 // FIXME: make this smarter for the SkImageFilter case (check for | 618 // FIXME: make this smarter for the SkImageFilter case (check for |
614 // pixel-moving filters) | 619 // pixel-moving filters) |
615 if (layer->filters().hasFilterThatMovesPixels() || layer->filter()) | 620 if (layer->filters().hasFilterThatMovesPixels() || layer->filter()) |
616 nearestAncestorThatMovesPixels = renderSurface; | 621 nearestAncestorThatMovesPixels = renderSurface; |
617 | 622 |
618 // The render surface clipRect is expressed in the space where this surf
ace draws, i.e. the same space as clipRectFromAncestor. | 623 // The render surface clipRect is expressed in the space where this surf
ace draws, i.e. the same space as clipRectFromAncestor. |
619 renderSurface->setIsClipped(ancestorClipsSubtree); | 624 renderSurface->setIsClipped(ancestorClipsSubtree); |
620 if (ancestorClipsSubtree) | 625 if (ancestorClipsSubtree) |
621 renderSurface->setClipRect(clipRectFromAncestor); | 626 renderSurface->setClipRect(clipRectFromAncestor); |
622 else | 627 else |
623 renderSurface->setClipRect(gfx::Rect()); | 628 renderSurface->setClipRect(gfx::Rect()); |
624 | 629 |
625 renderSurface->setNearestAncestorThatMovesPixels(nearestAncestorThatMove
sPixels); | 630 renderSurface->setNearestAncestorThatMovesPixels(nearestAncestorThatMove
sPixels); |
626 | 631 |
627 renderSurfaceLayerList.push_back(layer); | 632 renderSurfaceLayerList.push_back(layer); |
628 } else { | 633 } else { |
629 DCHECK(layer->parent()); | 634 DCHECK(layer->parent()); |
630 | 635 |
631 layer->setDrawTransform(drawTransform); | 636 // layerDrawProperties.drawTransform is computed above, before this if-e
lse statement. |
632 layer->setDrawTransformIsAnimating(animatingTransformToTarget); | 637 layerDrawProperties.drawTransformIsAnimating = animatingTransformToTarge
t; |
633 layer->setScreenSpaceTransformIsAnimating(animatingTransformToScreen); | 638 layerDrawProperties.screenSpaceTransformIsAnimating = animatingTransform
ToScreen; |
| 639 layerDrawProperties.drawOpacity = accumulatedDrawOpacity; |
| 640 layerDrawProperties.drawOpacityIsAnimating = drawOpacityIsAnimating; |
634 sublayerMatrix = combinedTransform; | 641 sublayerMatrix = combinedTransform; |
635 | 642 |
636 layer->setDrawOpacity(drawOpacity); | |
637 layer->setDrawOpacityIsAnimating(drawOpacityIsAnimating); | |
638 | |
639 layer->clearRenderSurface(); | 643 layer->clearRenderSurface(); |
640 | 644 |
641 // Layers without renderSurfaces directly inherit the ancestor's clip st
atus. | 645 // Layers without renderSurfaces directly inherit the ancestor's clip st
atus. |
642 subtreeShouldBeClipped = ancestorClipsSubtree; | 646 subtreeShouldBeClipped = ancestorClipsSubtree; |
643 if (ancestorClipsSubtree) | 647 if (ancestorClipsSubtree) |
644 clipRectForSubtree = clipRectFromAncestor; | 648 clipRectForSubtree = clipRectFromAncestor; |
645 | 649 |
646 // Layers that are not their own renderTarget will render into the targe
t of their nearest ancestor. | 650 // Layers that are not their own renderTarget will render into the targe
t of their nearest ancestor. |
647 layer->setRenderTarget(layer->parent()->renderTarget()); | 651 layerDrawProperties.renderTarget = layer->parent()->renderTarget(); |
648 } | 652 } |
649 | 653 |
650 gfx::Rect rectInTargetSpace = ToEnclosingRect(MathUtil::mapClippedRect(layer
->drawTransform(), contentRect)); | 654 gfx::Rect rectInTargetSpace = ToEnclosingRect(MathUtil::mapClippedRect(layer
->drawTransform(), contentRect)); |
651 | 655 |
652 if (layerClipsSubtree(layer)) { | 656 if (layerClipsSubtree(layer)) { |
653 subtreeShouldBeClipped = true; | 657 subtreeShouldBeClipped = true; |
654 if (ancestorClipsSubtree && !layer->renderSurface()) { | 658 if (ancestorClipsSubtree && !layer->renderSurface()) { |
655 clipRectForSubtree = clipRectFromAncestor; | 659 clipRectForSubtree = clipRectFromAncestor; |
656 clipRectForSubtree.Intersect(rectInTargetSpace); | 660 clipRectForSubtree.Intersect(rectInTargetSpace); |
657 } else | 661 } else |
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
694 } | 698 } |
695 | 699 |
696 // Compute the total drawableContentRect for this subtree (the rect is in ta
rgetSurface space) | 700 // Compute the total drawableContentRect for this subtree (the rect is in ta
rgetSurface space) |
697 gfx::Rect localDrawableContentRectOfSubtree = accumulatedDrawableContentRect
OfChildren; | 701 gfx::Rect localDrawableContentRectOfSubtree = accumulatedDrawableContentRect
OfChildren; |
698 if (layer->drawsContent()) | 702 if (layer->drawsContent()) |
699 localDrawableContentRectOfSubtree.Union(rectInTargetSpace); | 703 localDrawableContentRectOfSubtree.Union(rectInTargetSpace); |
700 if (subtreeShouldBeClipped) | 704 if (subtreeShouldBeClipped) |
701 localDrawableContentRectOfSubtree.Intersect(clipRectForSubtree); | 705 localDrawableContentRectOfSubtree.Intersect(clipRectForSubtree); |
702 | 706 |
703 // Compute the layer's drawable content rect (the rect is in targetSurface s
pace) | 707 // Compute the layer's drawable content rect (the rect is in targetSurface s
pace) |
704 gfx::Rect drawableContentRectOfLayer = rectInTargetSpace; | 708 layerDrawProperties.drawableContentRect = rectInTargetSpace; |
705 if (subtreeShouldBeClipped) | 709 if (subtreeShouldBeClipped) |
706 drawableContentRectOfLayer.Intersect(clipRectForSubtree); | 710 layerDrawProperties.drawableContentRect.Intersect(clipRectForSubtree); |
707 layer->setDrawableContentRect(drawableContentRectOfLayer); | |
708 | 711 |
709 // Tell the layer the rect that is clipped by. In theory we could use a | 712 // Tell the layer the rect that is clipped by. In theory we could use a |
710 // tighter clipRect here (drawableContentRect), but that actually does not | 713 // tighter clipRect here (drawableContentRect), but that actually does not |
711 // reduce how much would be drawn, and instead it would create unnecessary | 714 // reduce how much would be drawn, and instead it would create unnecessary |
712 // changes to scissor state affecting GPU performance. | 715 // changes to scissor state affecting GPU performance. |
713 layer->setIsClipped(subtreeShouldBeClipped); | 716 layerDrawProperties.isClipped = subtreeShouldBeClipped; |
714 if (subtreeShouldBeClipped) | 717 if (subtreeShouldBeClipped) |
715 layer->setClipRect(clipRectForSubtree); | 718 layerDrawProperties.clipRect = clipRectForSubtree; |
716 else { | 719 else { |
717 // Initialize the clipRect to a safe value that will not clip the | 720 // Initialize the clipRect to a safe value that will not clip the |
718 // layer, just in case clipping is still accidentally used. | 721 // layer, just in case clipping is still accidentally used. |
719 layer->setClipRect(rectInTargetSpace); | 722 layerDrawProperties.clipRect = rectInTargetSpace; |
720 } | 723 } |
721 | 724 |
722 // Compute the layer's visible content rect (the rect is in content space) | 725 // Compute the layer's visible content rect (the rect is in content space) |
723 gfx::Rect visibleContentRectOfLayer = calculateVisibleContentRect(layer); | 726 layerDrawProperties.visibleContentRect = calculateVisibleContentRect(layer); |
724 layer->setVisibleContentRect(visibleContentRectOfLayer); | |
725 | 727 |
726 // Compute the remaining properties for the render surface, if the layer has
one. | 728 // Compute the remaining properties for the render surface, if the layer has
one. |
727 if (isRootLayer(layer)) { | 729 if (isRootLayer(layer)) { |
728 // The root layer's surface's contentRect is always the entire viewport. | 730 // The root layer's surface's contentRect is always the entire viewport. |
729 DCHECK(layer->renderSurface()); | 731 DCHECK(layer->renderSurface()); |
730 layer->renderSurface()->setContentRect(clipRectFromAncestor); | 732 layer->renderSurface()->setContentRect(clipRectFromAncestor); |
731 } else if (layer->renderSurface() && !isRootLayer(layer)) { | 733 } else if (layer->renderSurface() && !isRootLayer(layer)) { |
732 RenderSurfaceType* renderSurface = layer->renderSurface(); | 734 RenderSurfaceType* renderSurface = layer->renderSurface(); |
733 gfx::Rect clippedContentRect = localDrawableContentRectOfSubtree; | 735 gfx::Rect clippedContentRect = localDrawableContentRectOfSubtree; |
734 | 736 |
(...skipping 253 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
988 | 990 |
989 foundLayer = currentLayer; | 991 foundLayer = currentLayer; |
990 break; | 992 break; |
991 } | 993 } |
992 | 994 |
993 // This can potentially return 0, which means the screenSpacePoint did not s
uccessfully hit test any layers, not even the root layer. | 995 // This can potentially return 0, which means the screenSpacePoint did not s
uccessfully hit test any layers, not even the root layer. |
994 return foundLayer; | 996 return foundLayer; |
995 } | 997 } |
996 | 998 |
997 } // namespace cc | 999 } // namespace cc |
OLD | NEW |