| 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 gfx::Transform surfaceToLayer(gfx::Transform::kSkipInitialization); |
| 61 if (!transform.GetInverse(&surfaceToLayer)) { |
| 62 // TODO(shawnsingh): Either we need to handle uninvertible transforms |
| 63 // here, or DCHECK that the transform is invertible. |
| 64 } |
| 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 gfx::Transform inversePartialLayerOriginTransform(gfx::Transform::kSkipIniti
alization); |
| 341 if (!partialLayerOriginTransform.GetInverse(&inversePartialLayerOriginTransf
orm)) { |
| 342 // TODO(shawnsingh): Either we need to handle uninvertible transforms |
| 343 // here, or DCHECK that the transform is invertible. |
| 344 } |
| 345 scrollCompensationForThisLayer.PreconcatTransform(inversePartialLayerOriginT
ransform); // Step 1 |
| 335 return scrollCompensationForThisLayer; | 346 return scrollCompensationForThisLayer; |
| 336 } | 347 } |
| 337 | 348 |
| 338 gfx::Transform computeScrollCompensationMatrixForChildren(Layer* currentLayer, c
onst gfx::Transform& currentParentMatrix, const gfx::Transform& currentScrollCom
pensation) | 349 gfx::Transform computeScrollCompensationMatrixForChildren(Layer* currentLayer, c
onst gfx::Transform& currentParentMatrix, const gfx::Transform& currentScrollCom
pensation) |
| 339 { | 350 { |
| 340 // The main thread (i.e. Layer) does not need to worry about scroll compensa
tion. | 351 // 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. | 352 // So we can just return an identity matrix here. |
| 342 return gfx::Transform(); | 353 return gfx::Transform(); |
| 343 } | 354 } |
| 344 | 355 |
| (...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 376 if (!layer->scrollDelta().IsZero()) { | 387 if (!layer->scrollDelta().IsZero()) { |
| 377 gfx::Transform scrollCompensationForThisLayer = computeScrollCompensatio
nForThisLayer(layer, parentMatrix); | 388 gfx::Transform scrollCompensationForThisLayer = computeScrollCompensatio
nForThisLayer(layer, parentMatrix); |
| 378 nextScrollCompensationMatrix.PreconcatTransform(scrollCompensationForThi
sLayer); | 389 nextScrollCompensationMatrix.PreconcatTransform(scrollCompensationForThi
sLayer); |
| 379 } | 390 } |
| 380 | 391 |
| 381 // If the layer created its own renderSurface, we have to adjust nextScrollC
ompensationMatrix. | 392 // 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. | 393 // 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 | 394 // 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 | 395 // Step 2: apply the scroll compensation |
| 385 // Step 3: transform back to the new surface. | 396 // Step 3: transform back to the new surface. |
| 386 if (layer->renderSurface() && !nextScrollCompensationMatrix.IsIdentity()) | 397 if (layer->renderSurface() && !nextScrollCompensationMatrix.IsIdentity()) { |
| 387 nextScrollCompensationMatrix = MathUtil::inverse(layer->renderSurface()-
>drawTransform()) * nextScrollCompensationMatrix * layer->renderSurface()->drawT
ransform(); | 398 gfx::Transform inverseSurfaceDrawTransform(gfx::Transform::kSkipInitiali
zation); |
| 399 if (!layer->renderSurface()->drawTransform().GetInverse(&inverseSurfaceD
rawTransform)) { |
| 400 // TODO(shawnsingh): Either we need to handle uninvertible transform
s |
| 401 // here, or DCHECK that the transform is invertible. |
| 402 } |
| 403 nextScrollCompensationMatrix = inverseSurfaceDrawTransform * nextScrollC
ompensationMatrix * layer->renderSurface()->drawTransform(); |
| 404 } |
| 388 | 405 |
| 389 return nextScrollCompensationMatrix; | 406 return nextScrollCompensationMatrix; |
| 390 } | 407 } |
| 391 | 408 |
| 392 static inline void updateLayerContentsScale(LayerImpl* layer, const gfx::Transfo
rm& combinedTransform, float deviceScaleFactor, float pageScaleFactor, bool anim
atingTransformToScreen) | 409 static inline void updateLayerContentsScale(LayerImpl* layer, const gfx::Transfo
rm& combinedTransform, float deviceScaleFactor, float pageScaleFactor, bool anim
atingTransformToScreen) |
| 393 { | 410 { |
| 394 } | 411 } |
| 395 | 412 |
| 396 static inline void updateLayerContentsScale(Layer* layer, const gfx::Transform&
combinedTransform, float deviceScaleFactor, float pageScaleFactor, bool animatin
gTransformToScreen) | 413 static inline void updateLayerContentsScale(Layer* layer, const gfx::Transform&
combinedTransform, float deviceScaleFactor, float pageScaleFactor, bool animatin
gTransformToScreen) |
| 397 { | 414 { |
| (...skipping 341 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 739 | 756 |
| 740 // FIXME: make this smarter for the SkImageFilter case (check for | 757 // FIXME: make this smarter for the SkImageFilter case (check for |
| 741 // pixel-moving filters) | 758 // pixel-moving filters) |
| 742 if (layer->filters().hasFilterThatMovesPixels() || layer->filter()) | 759 if (layer->filters().hasFilterThatMovesPixels() || layer->filter()) |
| 743 nearestAncestorThatMovesPixels = renderSurface; | 760 nearestAncestorThatMovesPixels = renderSurface; |
| 744 | 761 |
| 745 // The render surface clipRect is expressed in the space where this surf
ace draws, i.e. the same space as clipRectFromAncestor. | 762 // 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); | 763 renderSurface->setIsClipped(ancestorClipsSubtree); |
| 747 if (ancestorClipsSubtree) { | 764 if (ancestorClipsSubtree) { |
| 748 renderSurface->setClipRect(clipRectFromAncestor); | 765 renderSurface->setClipRect(clipRectFromAncestor); |
| 749 clipRectForSubtreeInDescendantSpace = gfx::ToEnclosingRect(MathUtil:
:projectClippedRect(MathUtil::inverse(renderSurface->drawTransform()), renderSur
face->clipRect())); | 766 |
| 767 gfx::Transform inverseSurfaceDrawTransform(gfx::Transform::kSkipInit
ialization); |
| 768 if (!renderSurface->drawTransform().GetInverse(&inverseSurfaceDrawTr
ansform)) { |
| 769 // TODO(shawnsingh): Either we need to handle uninvertible trans
forms |
| 770 // here, or DCHECK that the transform is invertible. |
| 771 } |
| 772 clipRectForSubtreeInDescendantSpace = gfx::ToEnclosingRect(MathUtil:
:projectClippedRect(inverseSurfaceDrawTransform, renderSurface->clipRect())); |
| 750 } else { | 773 } else { |
| 751 renderSurface->setClipRect(gfx::Rect()); | 774 renderSurface->setClipRect(gfx::Rect()); |
| 752 clipRectForSubtreeInDescendantSpace = clipRectFromAncestorInDescenda
ntSpace; | 775 clipRectForSubtreeInDescendantSpace = clipRectFromAncestorInDescenda
ntSpace; |
| 753 } | 776 } |
| 754 | 777 |
| 755 renderSurface->setNearestAncestorThatMovesPixels(nearestAncestorThatMove
sPixels); | 778 renderSurface->setNearestAncestorThatMovesPixels(nearestAncestorThatMove
sPixels); |
| 756 | 779 |
| 757 // If the new render surface is drawn translucent or with a non-integral
translation | 780 // 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. | 781 // then the subtree that gets drawn on this render surface cannot use LC
D text. |
| 759 subtreeCanUseLCDText = layerCanUseLCDText; | 782 subtreeCanUseLCDText = layerCanUseLCDText; |
| (...skipping 241 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1001 | 1024 |
| 1002 // The dummy layer list should not have been used. | 1025 // The dummy layer list should not have been used. |
| 1003 DCHECK(dummyLayerList.size() == 0); | 1026 DCHECK(dummyLayerList.size() == 0); |
| 1004 // A root layer renderSurface should always exist after calculateDrawPropert
ies. | 1027 // A root layer renderSurface should always exist after calculateDrawPropert
ies. |
| 1005 DCHECK(rootLayer->renderSurface()); | 1028 DCHECK(rootLayer->renderSurface()); |
| 1006 } | 1029 } |
| 1007 | 1030 |
| 1008 static bool pointHitsRect(const gfx::PointF& screenSpacePoint, const gfx::Transf
orm& localSpaceToScreenSpaceTransform, gfx::RectF localSpaceRect) | 1031 static bool pointHitsRect(const gfx::PointF& screenSpacePoint, const gfx::Transf
orm& localSpaceToScreenSpaceTransform, gfx::RectF localSpaceRect) |
| 1009 { | 1032 { |
| 1010 // If the transform is not invertible, then assume that this point doesn't h
it this rect. | 1033 // If the transform is not invertible, then assume that this point doesn't h
it this rect. |
| 1011 if (!localSpaceToScreenSpaceTransform.IsInvertible()) | 1034 gfx::Transform inverseLocalSpaceToScreenSpace(gfx::Transform::kSkipInitializ
ation); |
| 1035 if (!localSpaceToScreenSpaceTransform.GetInverse(&inverseLocalSpaceToScreenS
pace)) |
| 1012 return false; | 1036 return false; |
| 1013 | 1037 |
| 1014 // Transform the hit test point from screen space to the local space of the
given rect. | 1038 // Transform the hit test point from screen space to the local space of the
given rect. |
| 1015 bool clipped = false; | 1039 bool clipped = false; |
| 1016 gfx::PointF hitTestPointInLocalSpace = MathUtil::projectPoint(MathUtil::inve
rse(localSpaceToScreenSpaceTransform), screenSpacePoint, clipped); | 1040 gfx::PointF hitTestPointInLocalSpace = MathUtil::projectPoint(inverseLocalSp
aceToScreenSpace, screenSpacePoint, clipped); |
| 1017 | 1041 |
| 1018 // If projectPoint could not project to a valid value, then we assume that t
his point doesn't hit this rect. | 1042 // If projectPoint could not project to a valid value, then we assume that t
his point doesn't hit this rect. |
| 1019 if (clipped) | 1043 if (clipped) |
| 1020 return false; | 1044 return false; |
| 1021 | 1045 |
| 1022 return localSpaceRect.Contains(hitTestPointInLocalSpace); | 1046 return localSpaceRect.Contains(hitTestPointInLocalSpace); |
| 1023 } | 1047 } |
| 1024 | 1048 |
| 1025 static bool pointHitsRegion(gfx::PointF screenSpacePoint, const gfx::Transform&
screenSpaceTransform, const Region& layerSpaceRegion, float layerContentScaleX,
float layerContentScaleY) | 1049 static bool pointHitsRegion(gfx::PointF screenSpacePoint, const gfx::Transform&
screenSpaceTransform, const Region& layerSpaceRegion, float layerContentScaleX,
float layerContentScaleY) |
| 1026 { | 1050 { |
| 1027 // If the transform is not invertible, then assume that this point doesn't h
it this region. | 1051 // If the transform is not invertible, then assume that this point doesn't h
it this region. |
| 1028 if (!screenSpaceTransform.IsInvertible()) | 1052 gfx::Transform inverseScreenSpaceTransform(gfx::Transform::kSkipInitializati
on); |
| 1053 if (!screenSpaceTransform.GetInverse(&inverseScreenSpaceTransform)) |
| 1029 return false; | 1054 return false; |
| 1030 | 1055 |
| 1031 // Transform the hit test point from screen space to the local space of the
given region. | 1056 // Transform the hit test point from screen space to the local space of the
given region. |
| 1032 bool clipped = false; | 1057 bool clipped = false; |
| 1033 gfx::PointF hitTestPointInContentSpace = MathUtil::projectPoint(MathUtil::in
verse(screenSpaceTransform), screenSpacePoint, clipped); | 1058 gfx::PointF hitTestPointInContentSpace = MathUtil::projectPoint(inverseScree
nSpaceTransform, screenSpacePoint, clipped); |
| 1034 gfx::PointF hitTestPointInLayerSpace = gfx::ScalePoint(hitTestPointInContent
Space, 1 / layerContentScaleX, 1 / layerContentScaleY); | 1059 gfx::PointF hitTestPointInLayerSpace = gfx::ScalePoint(hitTestPointInContent
Space, 1 / layerContentScaleX, 1 / layerContentScaleY); |
| 1035 | 1060 |
| 1036 // If projectPoint could not project to a valid value, then we assume that t
his point doesn't hit this region. | 1061 // If projectPoint could not project to a valid value, then we assume that t
his point doesn't hit this region. |
| 1037 if (clipped) | 1062 if (clipped) |
| 1038 return false; | 1063 return false; |
| 1039 | 1064 |
| 1040 return layerSpaceRegion.Contains(gfx::ToRoundedPoint(hitTestPointInLayerSpac
e)); | 1065 return layerSpaceRegion.Contains(gfx::ToRoundedPoint(hitTestPointInLayerSpac
e)); |
| 1041 } | 1066 } |
| 1042 | 1067 |
| 1043 static bool pointIsClippedBySurfaceOrClipRect(const gfx::PointF& screenSpacePoin
t, LayerImpl* layer) | 1068 static bool pointIsClippedBySurfaceOrClipRect(const gfx::PointF& screenSpacePoin
t, LayerImpl* layer) |
| (...skipping 84 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1128 | 1153 |
| 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 | 1154 // 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 | 1155 // 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. | 1156 // hit point actually should not hit the layer. |
| 1132 if (pointIsClippedBySurfaceOrClipRect(screenSpacePoint, layerImpl)) | 1157 if (pointIsClippedBySurfaceOrClipRect(screenSpacePoint, layerImpl)) |
| 1133 return false; | 1158 return false; |
| 1134 | 1159 |
| 1135 return true; | 1160 return true; |
| 1136 } | 1161 } |
| 1137 } // namespace cc | 1162 } // namespace cc |
| OLD | NEW |