| 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 "base/debug/trace_event.h" | 9 #include "base/debug/trace_event.h" |
| 10 #include "cc/layer.h" | 10 #include "cc/layer.h" |
| (...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 49 // If the layer doesn't fill up the entire surface, then find the part of | 49 // If the layer doesn't fill up the entire surface, then find the part of |
| 50 // the surface rect where the layer could be visible. This avoids trying to | 50 // the surface rect where the layer could be visible. This avoids trying to |
| 51 // project surface rect points that are behind the projection point. | 51 // project surface rect points that are behind the projection point. |
| 52 gfx::Rect minimalSurfaceRect = targetSurfaceRect; | 52 gfx::Rect minimalSurfaceRect = targetSurfaceRect; |
| 53 minimalSurfaceRect.Intersect(layerRectInTargetSpace); | 53 minimalSurfaceRect.Intersect(layerRectInTargetSpace); |
| 54 | 54 |
| 55 // Project the corners of the target surface rect into the layer space. | 55 // Project the corners of the target surface rect into the layer space. |
| 56 // This bounding rectangle may be larger than it needs to be (being | 56 // This bounding rectangle may be larger than it needs to be (being |
| 57 // axis-aligned), but is a reasonable filter on the space to consider. | 57 // axis-aligned), but is a reasonable filter on the space to consider. |
| 58 // Non-invertible transforms will create an empty rect here. | 58 // Non-invertible transforms will create an empty rect here. |
| 59 const gfx::Transform surfaceToLayer = MathUtil::inverse(transform); | 59 |
| 60 // TODO: Either we need to handle uninvertible transforms here, or DCHECK |
| 61 // that the transform is invertible. |
| 62 gfx::Transform surfaceToLayer(gfx::Transform::kSkipInitialization); |
| 63 if (!transform.GetInverse(&surfaceToLayer)) |
| 64 surfaceToLayer.MakeIdentity(); |
| 60 gfx::Rect layerRect = gfx::ToEnclosingRect(MathUtil::projectClippedRect(surf
aceToLayer, gfx::RectF(minimalSurfaceRect))); | 65 gfx::Rect layerRect = gfx::ToEnclosingRect(MathUtil::projectClippedRect(surf
aceToLayer, gfx::RectF(minimalSurfaceRect))); |
| 61 layerRect.Intersect(layerBoundRect); | 66 layerRect.Intersect(layerBoundRect); |
| 62 return layerRect; | 67 return layerRect; |
| 63 } | 68 } |
| 64 | 69 |
| 65 gfx::Rect LayerTreeHostCommon::calculateVisibleRect(const gfx::Rect& targetSurfa
ceRect, const gfx::Rect& layerBoundRect, const gfx::Transform& transform) | 70 gfx::Rect LayerTreeHostCommon::calculateVisibleRect(const gfx::Rect& targetSurfa
ceRect, const gfx::Rect& layerBoundRect, const gfx::Transform& transform) |
| 66 { | 71 { |
| 67 gfx::Rect layerInSurfaceSpace = MathUtil::mapClippedRect(transform, layerBou
ndRect); | 72 gfx::Rect layerInSurfaceSpace = MathUtil::mapClippedRect(transform, layerBou
ndRect); |
| 68 return calculateVisibleRectWithCachedLayerRect(targetSurfaceRect, layerBound
Rect, layerInSurfaceSpace, transform); | 73 return calculateVisibleRectWithCachedLayerRect(targetSurfaceRect, layerBound
Rect, layerInSurfaceSpace, transform); |
| 69 } | 74 } |
| (...skipping 254 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 324 // These steps create a matrix that both start and end in targetSurfaceSpace
. So this matrix can | 329 // These steps create a matrix that both start and end in targetSurfaceSpace
. So this matrix can |
| 325 // pre-multiply any fixed-position layer's drawTransform to undo the scrollD
eltas -- as long as | 330 // pre-multiply any fixed-position layer's drawTransform to undo the scrollD
eltas -- as long as |
| 326 // that fixed position layer is fixed onto the same renderTarget as this scr
ollingLayer. | 331 // that fixed position layer is fixed onto the same renderTarget as this scr
ollingLayer. |
| 327 // | 332 // |
| 328 | 333 |
| 329 gfx::Transform partialLayerOriginTransform = parentMatrix; | 334 gfx::Transform partialLayerOriginTransform = parentMatrix; |
| 330 partialLayerOriginTransform.PreconcatTransform(scrollingLayer->implTransform
()); | 335 partialLayerOriginTransform.PreconcatTransform(scrollingLayer->implTransform
()); |
| 331 | 336 |
| 332 gfx::Transform scrollCompensationForThisLayer = partialLayerOriginTransform;
// Step 3 | 337 gfx::Transform scrollCompensationForThisLayer = partialLayerOriginTransform;
// Step 3 |
| 333 scrollCompensationForThisLayer.Translate(scrollingLayer->scrollDelta().x(),
scrollingLayer->scrollDelta().y()); // Step 2 | 338 scrollCompensationForThisLayer.Translate(scrollingLayer->scrollDelta().x(),
scrollingLayer->scrollDelta().y()); // Step 2 |
| 334 scrollCompensationForThisLayer.PreconcatTransform(MathUtil::inverse(partialL
ayerOriginTransform)); // Step 1 | 339 |
| 340 // TODO: Either we need to properly handle uninvertible |
| 341 // partiaLayerOriginTransform, or we need to DCHECK that it is |
| 342 // invertible. |
| 343 gfx::Transform inversePartialLayerOriginTransform(gfx::Transform::kSkipIniti
alization); |
| 344 if (!partialLayerOriginTransform.GetInverse(&inversePartialLayerOriginTransf
orm)) |
| 345 inversePartialLayerOriginTransform.MakeIdentity(); |
| 346 scrollCompensationForThisLayer.PreconcatTransform(inversePartialLayerOriginT
ransform); // Step 1 |
| 335 return scrollCompensationForThisLayer; | 347 return scrollCompensationForThisLayer; |
| 336 } | 348 } |
| 337 | 349 |
| 338 gfx::Transform computeScrollCompensationMatrixForChildren(Layer* currentLayer, c
onst gfx::Transform& currentParentMatrix, const gfx::Transform& currentScrollCom
pensation) | 350 gfx::Transform computeScrollCompensationMatrixForChildren(Layer* currentLayer, c
onst gfx::Transform& currentParentMatrix, const gfx::Transform& currentScrollCom
pensation) |
| 339 { | 351 { |
| 340 // The main thread (i.e. Layer) does not need to worry about scroll compensa
tion. | 352 // The main thread (i.e. Layer) does not need to worry about scroll compensa
tion. |
| 341 // So we can just return an identity matrix here. | 353 // So we can just return an identity matrix here. |
| 342 return gfx::Transform(); | 354 return gfx::Transform(); |
| 343 } | 355 } |
| 344 | 356 |
| (...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 376 if (!layer->scrollDelta().IsZero()) { | 388 if (!layer->scrollDelta().IsZero()) { |
| 377 gfx::Transform scrollCompensationForThisLayer = computeScrollCompensatio
nForThisLayer(layer, parentMatrix); | 389 gfx::Transform scrollCompensationForThisLayer = computeScrollCompensatio
nForThisLayer(layer, parentMatrix); |
| 378 nextScrollCompensationMatrix.PreconcatTransform(scrollCompensationForThi
sLayer); | 390 nextScrollCompensationMatrix.PreconcatTransform(scrollCompensationForThi
sLayer); |
| 379 } | 391 } |
| 380 | 392 |
| 381 // If the layer created its own renderSurface, we have to adjust nextScrollC
ompensationMatrix. | 393 // If the layer created its own renderSurface, we have to adjust nextScrollC
ompensationMatrix. |
| 382 // The adjustment allows us to continue using the scrollCompensation on the
next surface. | 394 // The adjustment allows us to continue using the scrollCompensation on the
next surface. |
| 383 // Step 1 (right-most in the math): transform from the new surface to the o
riginal ancestor surface | 395 // Step 1 (right-most in the math): transform from the new surface to the o
riginal ancestor surface |
| 384 // Step 2: apply the scroll compensation | 396 // Step 2: apply the scroll compensation |
| 385 // Step 3: transform back to the new surface. | 397 // Step 3: transform back to the new surface. |
| 386 if (layer->renderSurface() && !nextScrollCompensationMatrix.IsIdentity()) | 398 if (layer->renderSurface() && !nextScrollCompensationMatrix.IsIdentity()) { |
| 387 nextScrollCompensationMatrix = MathUtil::inverse(layer->renderSurface()-
>drawTransform()) * nextScrollCompensationMatrix * layer->renderSurface()->drawT
ransform(); | 399 // TODO: Either we need to properly handle uninvertible drawTransforms, |
| 400 // or we need to DCHECK that it is invertible. |
| 401 gfx::Transform inverseSurfaceDrawTransform(gfx::Transform::kSkipInitiali
zation); |
| 402 if (!layer->renderSurface()->drawTransform().GetInverse(&inverseSurfaceD
rawTransform)) |
| 403 inverseSurfaceDrawTransform.MakeIdentity(); |
| 404 nextScrollCompensationMatrix = inverseSurfaceDrawTransform * nextScrollC
ompensationMatrix * layer->renderSurface()->drawTransform(); |
| 405 } |
| 388 | 406 |
| 389 return nextScrollCompensationMatrix; | 407 return nextScrollCompensationMatrix; |
| 390 } | 408 } |
| 391 | 409 |
| 392 static inline void updateLayerContentsScale(LayerImpl* layer, const gfx::Transfo
rm& combinedTransform, float deviceScaleFactor, float pageScaleFactor, bool anim
atingTransformToScreen) | 410 static inline void updateLayerContentsScale(LayerImpl* layer, const gfx::Transfo
rm& combinedTransform, float deviceScaleFactor, float pageScaleFactor, bool anim
atingTransformToScreen) |
| 393 { | 411 { |
| 394 } | 412 } |
| 395 | 413 |
| 396 static inline void updateLayerContentsScale(Layer* layer, const gfx::Transform&
combinedTransform, float deviceScaleFactor, float pageScaleFactor, bool animatin
gTransformToScreen) | 414 static inline void updateLayerContentsScale(Layer* layer, const gfx::Transform&
combinedTransform, float deviceScaleFactor, float pageScaleFactor, bool animatin
gTransformToScreen) |
| 397 { | 415 { |
| (...skipping 341 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 739 | 757 |
| 740 // FIXME: make this smarter for the SkImageFilter case (check for | 758 // FIXME: make this smarter for the SkImageFilter case (check for |
| 741 // pixel-moving filters) | 759 // pixel-moving filters) |
| 742 if (layer->filters().hasFilterThatMovesPixels() || layer->filter()) | 760 if (layer->filters().hasFilterThatMovesPixels() || layer->filter()) |
| 743 nearestAncestorThatMovesPixels = renderSurface; | 761 nearestAncestorThatMovesPixels = renderSurface; |
| 744 | 762 |
| 745 // The render surface clipRect is expressed in the space where this surf
ace draws, i.e. the same space as clipRectFromAncestor. | 763 // The render surface clipRect is expressed in the space where this surf
ace draws, i.e. the same space as clipRectFromAncestor. |
| 746 renderSurface->setIsClipped(ancestorClipsSubtree); | 764 renderSurface->setIsClipped(ancestorClipsSubtree); |
| 747 if (ancestorClipsSubtree) { | 765 if (ancestorClipsSubtree) { |
| 748 renderSurface->setClipRect(clipRectFromAncestor); | 766 renderSurface->setClipRect(clipRectFromAncestor); |
| 749 clipRectForSubtreeInDescendantSpace = gfx::ToEnclosingRect(MathUtil:
:projectClippedRect(MathUtil::inverse(renderSurface->drawTransform()), renderSur
face->clipRect())); | 767 |
| 768 // TODO: Either we need to properly handle uninvertible drawTransfor
ms, |
| 769 // or we need to DCHECK that it is invertible. |
| 770 gfx::Transform inverseSurfaceDrawTransform(gfx::Transform::kSkipInit
ialization); |
| 771 if (!renderSurface->drawTransform().GetInverse(&inverseSurfaceDrawTr
ansform)) |
| 772 inverseSurfaceDrawTransform.MakeIdentity(); |
| 773 clipRectForSubtreeInDescendantSpace = gfx::ToEnclosingRect(MathUtil:
:projectClippedRect(inverseSurfaceDrawTransform, renderSurface->clipRect())); |
| 750 } else { | 774 } else { |
| 751 renderSurface->setClipRect(gfx::Rect()); | 775 renderSurface->setClipRect(gfx::Rect()); |
| 752 clipRectForSubtreeInDescendantSpace = clipRectFromAncestorInDescenda
ntSpace; | 776 clipRectForSubtreeInDescendantSpace = clipRectFromAncestorInDescenda
ntSpace; |
| 753 } | 777 } |
| 754 | 778 |
| 755 renderSurface->setNearestAncestorThatMovesPixels(nearestAncestorThatMove
sPixels); | 779 renderSurface->setNearestAncestorThatMovesPixels(nearestAncestorThatMove
sPixels); |
| 756 | 780 |
| 757 // If the new render surface is drawn translucent or with a non-integral
translation | 781 // If the new render surface is drawn translucent or with a non-integral
translation |
| 758 // then the subtree that gets drawn on this render surface cannot use LC
D text. | 782 // then the subtree that gets drawn on this render surface cannot use LC
D text. |
| 759 subtreeCanUseLCDText = layerCanUseLCDText; | 783 subtreeCanUseLCDText = layerCanUseLCDText; |
| (...skipping 241 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1001 | 1025 |
| 1002 // The dummy layer list should not have been used. | 1026 // The dummy layer list should not have been used. |
| 1003 DCHECK(dummyLayerList.size() == 0); | 1027 DCHECK(dummyLayerList.size() == 0); |
| 1004 // A root layer renderSurface should always exist after calculateDrawPropert
ies. | 1028 // A root layer renderSurface should always exist after calculateDrawPropert
ies. |
| 1005 DCHECK(rootLayer->renderSurface()); | 1029 DCHECK(rootLayer->renderSurface()); |
| 1006 } | 1030 } |
| 1007 | 1031 |
| 1008 static bool pointHitsRect(const gfx::PointF& screenSpacePoint, const gfx::Transf
orm& localSpaceToScreenSpaceTransform, gfx::RectF localSpaceRect) | 1032 static bool pointHitsRect(const gfx::PointF& screenSpacePoint, const gfx::Transf
orm& localSpaceToScreenSpaceTransform, gfx::RectF localSpaceRect) |
| 1009 { | 1033 { |
| 1010 // If the transform is not invertible, then assume that this point doesn't h
it this rect. | 1034 // If the transform is not invertible, then assume that this point doesn't h
it this rect. |
| 1011 if (!localSpaceToScreenSpaceTransform.IsInvertible()) | 1035 gfx::Transform inverseLocalSpaceToScreenSpace(gfx::Transform::kSkipInitializ
ation); |
| 1036 if (!localSpaceToScreenSpaceTransform.GetInverse(&inverseLocalSpaceToScreenS
pace)) |
| 1012 return false; | 1037 return false; |
| 1013 | 1038 |
| 1014 // Transform the hit test point from screen space to the local space of the
given rect. | 1039 // Transform the hit test point from screen space to the local space of the
given rect. |
| 1015 bool clipped = false; | 1040 bool clipped = false; |
| 1016 gfx::PointF hitTestPointInLocalSpace = MathUtil::projectPoint(MathUtil::inve
rse(localSpaceToScreenSpaceTransform), screenSpacePoint, clipped); | 1041 gfx::PointF hitTestPointInLocalSpace = MathUtil::projectPoint(inverseLocalSp
aceToScreenSpace, screenSpacePoint, clipped); |
| 1017 | 1042 |
| 1018 // If projectPoint could not project to a valid value, then we assume that t
his point doesn't hit this rect. | 1043 // If projectPoint could not project to a valid value, then we assume that t
his point doesn't hit this rect. |
| 1019 if (clipped) | 1044 if (clipped) |
| 1020 return false; | 1045 return false; |
| 1021 | 1046 |
| 1022 return localSpaceRect.Contains(hitTestPointInLocalSpace); | 1047 return localSpaceRect.Contains(hitTestPointInLocalSpace); |
| 1023 } | 1048 } |
| 1024 | 1049 |
| 1025 static bool pointHitsRegion(gfx::PointF screenSpacePoint, const gfx::Transform&
screenSpaceTransform, const Region& layerSpaceRegion, float layerContentScaleX,
float layerContentScaleY) | 1050 static bool pointHitsRegion(gfx::PointF screenSpacePoint, const gfx::Transform&
screenSpaceTransform, const Region& layerSpaceRegion, float layerContentScaleX,
float layerContentScaleY) |
| 1026 { | 1051 { |
| 1027 // If the transform is not invertible, then assume that this point doesn't h
it this region. | 1052 // If the transform is not invertible, then assume that this point doesn't h
it this region. |
| 1028 if (!screenSpaceTransform.IsInvertible()) | 1053 gfx::Transform inverseScreenSpaceTransform(gfx::Transform::kSkipInitializati
on); |
| 1054 if (!screenSpaceTransform.GetInverse(&inverseScreenSpaceTransform)) |
| 1029 return false; | 1055 return false; |
| 1030 | 1056 |
| 1031 // Transform the hit test point from screen space to the local space of the
given region. | 1057 // Transform the hit test point from screen space to the local space of the
given region. |
| 1032 bool clipped = false; | 1058 bool clipped = false; |
| 1033 gfx::PointF hitTestPointInContentSpace = MathUtil::projectPoint(MathUtil::in
verse(screenSpaceTransform), screenSpacePoint, clipped); | 1059 gfx::PointF hitTestPointInContentSpace = MathUtil::projectPoint(inverseScree
nSpaceTransform, screenSpacePoint, clipped); |
| 1034 gfx::PointF hitTestPointInLayerSpace = gfx::ScalePoint(hitTestPointInContent
Space, 1 / layerContentScaleX, 1 / layerContentScaleY); | 1060 gfx::PointF hitTestPointInLayerSpace = gfx::ScalePoint(hitTestPointInContent
Space, 1 / layerContentScaleX, 1 / layerContentScaleY); |
| 1035 | 1061 |
| 1036 // If projectPoint could not project to a valid value, then we assume that t
his point doesn't hit this region. | 1062 // If projectPoint could not project to a valid value, then we assume that t
his point doesn't hit this region. |
| 1037 if (clipped) | 1063 if (clipped) |
| 1038 return false; | 1064 return false; |
| 1039 | 1065 |
| 1040 return layerSpaceRegion.Contains(gfx::ToRoundedPoint(hitTestPointInLayerSpac
e)); | 1066 return layerSpaceRegion.Contains(gfx::ToRoundedPoint(hitTestPointInLayerSpac
e)); |
| 1041 } | 1067 } |
| 1042 | 1068 |
| 1043 static bool pointIsClippedBySurfaceOrClipRect(const gfx::PointF& screenSpacePoin
t, LayerImpl* layer) | 1069 static bool pointIsClippedBySurfaceOrClipRect(const gfx::PointF& screenSpacePoin
t, LayerImpl* layer) |
| (...skipping 84 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1128 | 1154 |
| 1129 // At this point, we think the point does hit the touch event handler region o
n the layer, but we need to walk up | 1155 // At this point, we think the point does hit the touch event handler region o
n the layer, but we need to walk up |
| 1130 // the parents to ensure that the layer was not clipped in such a way that the | 1156 // the parents to ensure that the layer was not clipped in such a way that the |
| 1131 // hit point actually should not hit the layer. | 1157 // hit point actually should not hit the layer. |
| 1132 if (pointIsClippedBySurfaceOrClipRect(screenSpacePoint, layerImpl)) | 1158 if (pointIsClippedBySurfaceOrClipRect(screenSpacePoint, layerImpl)) |
| 1133 return false; | 1159 return false; |
| 1134 | 1160 |
| 1135 return true; | 1161 return true; |
| 1136 } | 1162 } |
| 1137 } // namespace cc | 1163 } // namespace cc |
| OLD | NEW |