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 |