Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(257)

Side by Side Diff: sky/engine/core/rendering/RenderLayer.cpp

Issue 937023002: Merge hitTestLayerByApplyingTransform into hitTestLayer. (Closed) Base URL: git@github.com:domokit/mojo.git@master
Patch Set: fix comment Created 5 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « sky/engine/core/rendering/RenderLayer.h ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 /* 1 /*
2 * Copyright (C) 2006, 2007, 2008, 2009, 2010, 2011, 2012 Apple Inc. All rights reserved. 2 * Copyright (C) 2006, 2007, 2008, 2009, 2010, 2011, 2012 Apple Inc. All rights reserved.
3 * 3 *
4 * Portions are Copyright (C) 1998 Netscape Communications Corporation. 4 * Portions are Copyright (C) 1998 Netscape Communications Corporation.
5 * 5 *
6 * Other contributors: 6 * Other contributors:
7 * Robert O'Callahan <roc+@cs.cmu.edu> 7 * Robert O'Callahan <roc+@cs.cmu.edu>
8 * David Baron <dbaron@fas.harvard.edu> 8 * David Baron <dbaron@fas.harvard.edu>
9 * Christian Biesinger <cbiesinger@web.de> 9 * Christian Biesinger <cbiesinger@web.de>
10 * Randall Jesup <rjesup@wgate.com> 10 * Randall Jesup <rjesup@wgate.com>
(...skipping 791 matching lines...) Expand 10 before | Expand all | Expand 10 after
802 ASSERT(isSelfPaintingLayer() || hasSelfPaintingLayerDescendant()); 802 ASSERT(isSelfPaintingLayer() || hasSelfPaintingLayerDescendant());
803 803
804 // RenderView should make sure to update layout before entering hit testing 804 // RenderView should make sure to update layout before entering hit testing
805 ASSERT(!renderer()->frame()->view()->layoutPending()); 805 ASSERT(!renderer()->frame()->view()->layoutPending());
806 ASSERT(!renderer()->document().renderView()->needsLayout()); 806 ASSERT(!renderer()->document().renderView()->needsLayout());
807 807
808 LayoutRect hitTestArea = renderer()->view()->documentRect(); 808 LayoutRect hitTestArea = renderer()->view()->documentRect();
809 if (!request.ignoreClipping()) 809 if (!request.ignoreClipping())
810 hitTestArea.intersect(frameVisibleRect(renderer())); 810 hitTestArea.intersect(frameVisibleRect(renderer()));
811 811
812 RenderLayer* insideLayer = hitTestLayer(this, 0, request, result, hitTestAre a, hitTestLocation, false); 812 RenderLayer* insideLayer = hitTestLayer(this, 0, request, result, hitTestAre a, hitTestLocation);
813 if (!insideLayer) { 813 if (!insideLayer) {
814 // We didn't hit any layer. If we are the root layer and the mouse is -- or just was -- down, 814 // We didn't hit any layer. If we are the root layer and the mouse is -- or just was -- down,
815 // return ourselves. We do this so mouse events continue getting deliver ed after a drag has 815 // return ourselves. We do this so mouse events continue getting deliver ed after a drag has
816 // exited the WebView, and so hit testing over a scrollbar hits the cont ent document. 816 // exited the WebView, and so hit testing over a scrollbar hits the cont ent document.
817 if ((request.active() || request.release()) && isRootLayer()) { 817 if ((request.active() || request.release()) && isRootLayer()) {
818 renderer()->updateHitTestResult(result, hitTestLocation.point()); 818 renderer()->updateHitTestResult(result, hitTestLocation.point());
819 insideLayer = this; 819 insideLayer = this;
820 } 820 }
821 } 821 }
822 return insideLayer; 822 return insideLayer;
(...skipping 84 matching lines...) Expand 10 before | Expand all | Expand 10 after
907 907
908 // hitTestLocation and hitTestRect are relative to rootLayer. 908 // hitTestLocation and hitTestRect are relative to rootLayer.
909 // A 'flattening' layer is one preserves3D() == false. 909 // A 'flattening' layer is one preserves3D() == false.
910 // transformState.m_accumulatedTransform holds the transform from the containing flattening layer. 910 // transformState.m_accumulatedTransform holds the transform from the containing flattening layer.
911 // transformState.m_lastPlanarPoint is the hitTestLocation in the plane of the c ontaining flattening layer. 911 // transformState.m_lastPlanarPoint is the hitTestLocation in the plane of the c ontaining flattening layer.
912 // transformState.m_lastPlanarQuad is the hitTestRect as a quad in the plane of the containing flattening layer. 912 // transformState.m_lastPlanarQuad is the hitTestRect as a quad in the plane of the containing flattening layer.
913 // 913 //
914 // If zOffset is non-null (which indicates that the caller wants z offset inform ation), 914 // If zOffset is non-null (which indicates that the caller wants z offset inform ation),
915 // *zOffset on return is the z offset of the hit point relative to the containi ng flattening layer. 915 // *zOffset on return is the z offset of the hit point relative to the containi ng flattening layer.
916 RenderLayer* RenderLayer::hitTestLayer(RenderLayer* rootLayer, RenderLayer* cont ainerLayer, const HitTestRequest& request, HitTestResult& result, 916 RenderLayer* RenderLayer::hitTestLayer(RenderLayer* rootLayer, RenderLayer* cont ainerLayer, const HitTestRequest& request, HitTestResult& result,
917 const LayoutRect& hitTestRect, const HitT estLocation& hitTestLocation, bool appliedTransform, 917 const LayoutRect& hitTestRect, const HitT estLocation& hitTestLocation,
918 const HitTestingTransformState* transform State, double* zOffset) 918 const HitTestingTransformState* transform State, double* zOffset)
919 { 919 {
920 if (!isSelfPaintingLayer() && !hasSelfPaintingLayerDescendant()) 920 if (!isSelfPaintingLayer() && !hasSelfPaintingLayerDescendant())
921 return 0; 921 return 0;
922 922
923 // The natural thing would be to keep HitTestingTransformState on the stack, but it's big, so we heap-allocate. 923 // The natural thing would be to keep HitTestingTransformState on the stack, but it's big, so we heap-allocate.
924 RefPtr<HitTestingTransformState> localTransformState;
925
926 LayoutRect localHitTestRect = hitTestRect;
927 HitTestLocation localHitTestLocation = hitTestLocation;
928
929 // We need transform state for the first time, or to offset the container st ate, or to accumulate the new transform.
930 if (transform() || transformState || m_has3DTransformedDescendant || preserv es3D())
931 localTransformState = createLocalTransformState(rootLayer, containerLaye r, localHitTestRect, localHitTestLocation, transformState);
924 932
925 // Apply a transform if we have one. 933 // Apply a transform if we have one.
926 if (transform() && !appliedTransform) { 934 if (transform()) {
927 // Make sure the parent's clip rects have been calculated. 935 // Make sure the parent's clip rects have been calculated.
928 if (parent()) { 936 if (parent()) {
929 ClipRect clipRect = clipper().backgroundClipRect(ClipRectsContext(ro otLayer, RootRelativeClipRects)); 937 ClipRect clipRect = clipper().backgroundClipRect(ClipRectsContext(ro otLayer, RootRelativeClipRects));
930 // Go ahead and test the enclosing clip now. 938 // Go ahead and test the enclosing clip now.
931 if (!clipRect.intersects(hitTestLocation)) 939 if (!clipRect.intersects(localHitTestLocation))
932 return 0; 940 return 0;
933 } 941 }
934 942
935 return hitTestLayerByApplyingTransform(rootLayer, containerLayer, reques t, result, hitTestRect, hitTestLocation, transformState, zOffset); 943 // If the transform can't be inverted, then don't hit test this layer at all.
944 if (!localTransformState->m_accumulatedTransform.isInvertible())
945 return 0;
946
947 // Compute the point and the hit test rect in the coords of this layer b y using the values
948 // from the transformState, which store the point and quad in the coords of the last flattened
949 // layer, and the accumulated transform which lets up map through preser ve-3d layers.
950 //
951 // We can't just map hitTestLocation and hitTestRect because they may ha ve been flattened (losing z)
952 // by our container.
953 FloatPoint localPoint = localTransformState->mappedPoint();
954 FloatQuad localPointQuad = localTransformState->mappedQuad();
955 localHitTestRect = localTransformState->boundsOfMappedArea();
956 if (localHitTestLocation.isRectBasedTest())
957 localHitTestLocation = HitTestLocation(localPoint, localPointQuad);
958 else
959 localHitTestLocation = HitTestLocation(localPoint);
960
961 // Now do a hit test with the root layer shifted to be us.
962 rootLayer = this;
936 } 963 }
937 964
938 // Ensure our lists and 3d status are up-to-date. 965 // Ensure our lists and 3d status are up-to-date.
939 m_stackingNode->updateLayerListsIfNeeded(); 966 m_stackingNode->updateLayerListsIfNeeded();
940 update3DTransformedDescendantStatus(); 967 update3DTransformedDescendantStatus();
941 968
942 RefPtr<HitTestingTransformState> localTransformState;
943 if (appliedTransform) {
944 // We computed the correct state in the caller (above code), so just ref erence it.
945 ASSERT(transformState);
946 localTransformState = const_cast<HitTestingTransformState*>(transformSta te);
947 } else if (transformState || m_has3DTransformedDescendant || preserves3D()) {
948 // We need transform state for the first time, or to offset the containe r state, so create it here.
949 localTransformState = createLocalTransformState(rootLayer, containerLaye r, hitTestRect, hitTestLocation, transformState);
950 }
951
952 // Check for hit test on backface if backface-visibility is 'hidden' 969 // Check for hit test on backface if backface-visibility is 'hidden'
953 if (localTransformState && renderer()->style()->backfaceVisibility() == Back faceVisibilityHidden) { 970 if (localTransformState && renderer()->style()->backfaceVisibility() == Back faceVisibilityHidden) {
954 TransformationMatrix invertedMatrix = localTransformState->m_accumulated Transform.inverse(); 971 TransformationMatrix invertedMatrix = localTransformState->m_accumulated Transform.inverse();
955 // If the z-vector of the matrix is negative, the back is facing towards the viewer. 972 // If the z-vector of the matrix is negative, the back is facing towards the viewer.
956 if (invertedMatrix.m33() < 0) 973 if (invertedMatrix.m33() < 0)
957 return 0; 974 return 0;
958 } 975 }
959 976
960 RefPtr<HitTestingTransformState> unflattenedTransformState = localTransformS tate; 977 RefPtr<HitTestingTransformState> unflattenedTransformState = localTransformS tate;
961 if (localTransformState && !preserves3D()) { 978 if (localTransformState && !preserves3D()) {
(...skipping 18 matching lines...) Expand all
980 } else if (zOffset) { 997 } else if (zOffset) {
981 zOffsetForDescendantsPtr = 0; 998 zOffsetForDescendantsPtr = 0;
982 // Container needs us to give back a z offset for the hit layer. 999 // Container needs us to give back a z offset for the hit layer.
983 zOffsetForContentsPtr = zOffset; 1000 zOffsetForContentsPtr = zOffset;
984 } 1001 }
985 1002
986 // This variable tracks which layer the mouse ends up being inside. 1003 // This variable tracks which layer the mouse ends up being inside.
987 RenderLayer* candidateLayer = 0; 1004 RenderLayer* candidateLayer = 0;
988 1005
989 // Begin by walking our list of positive layers from highest z-index down to the lowest z-index. 1006 // Begin by walking our list of positive layers from highest z-index down to the lowest z-index.
990 RenderLayer* hitLayer = hitTestChildren(PositiveZOrderChildren, rootLayer, r equest, result, hitTestRect, hitTestLocation, 1007 RenderLayer* hitLayer = hitTestChildren(PositiveZOrderChildren, rootLayer, r equest, result, localHitTestRect, localHitTestLocation,
991 localTransformState.get(), zOffsetForDes cendantsPtr, zOffset, unflattenedTransformState.get(), depthSortDescendants); 1008 localTransformState.get(), zOffsetForDes cendantsPtr, zOffset, unflattenedTransformState.get(), depthSortDescendants);
992 if (hitLayer) { 1009 if (hitLayer) {
993 if (!depthSortDescendants) 1010 if (!depthSortDescendants)
994 return hitLayer; 1011 return hitLayer;
995 candidateLayer = hitLayer; 1012 candidateLayer = hitLayer;
996 } 1013 }
997 1014
998 // Now check our overflow objects. 1015 // Now check our overflow objects.
999 hitLayer = hitTestChildren(NormalFlowChildren, rootLayer, request, result, h itTestRect, hitTestLocation, 1016 hitLayer = hitTestChildren(NormalFlowChildren, rootLayer, request, result, l ocalHitTestRect, localHitTestLocation,
1000 localTransformState.get(), zOffsetForDescendantsPtr, zOffset, unflattenedTransformState.get(), depthSortDescendants); 1017 localTransformState.get(), zOffsetForDescendantsPtr, zOffset, unflattenedTransformState.get(), depthSortDescendants);
1001 if (hitLayer) { 1018 if (hitLayer) {
1002 if (!depthSortDescendants) 1019 if (!depthSortDescendants)
1003 return hitLayer; 1020 return hitLayer;
1004 candidateLayer = hitLayer; 1021 candidateLayer = hitLayer;
1005 } 1022 }
1006 1023
1007 LayoutRect layerBounds; 1024 LayoutRect layerBounds;
1008 // FIXME(sky): Remove foregroundRect. It's unused. 1025 // FIXME(sky): Remove foregroundRect. It's unused.
1009 ClipRect contentRect, foregroundRect; 1026 ClipRect contentRect, foregroundRect;
1010 ClipRectsContext clipRectsContext(rootLayer, RootRelativeClipRects); 1027 ClipRectsContext clipRectsContext(rootLayer, RootRelativeClipRects);
1011 clipper().calculateRects(clipRectsContext, hitTestRect, layerBounds, content Rect, foregroundRect); 1028 clipper().calculateRects(clipRectsContext, localHitTestRect, layerBounds, co ntentRect, foregroundRect);
1012 1029
1013 // Next we want to see if the mouse pos is inside the child RenderObjects of the layer. 1030 // Next we want to see if the mouse pos is inside the child RenderObjects of the layer.
1014 if (isSelfPaintingLayer() && contentRect.intersects(hitTestLocation)) { 1031 if (isSelfPaintingLayer() && contentRect.intersects(localHitTestLocation)) {
1015 // Hit test with a temporary HitTestResult, because we only want to comm it to 'result' if we know we're frontmost. 1032 // Hit test with a temporary HitTestResult, because we only want to comm it to 'result' if we know we're frontmost.
1016 HitTestResult tempResult(result.hitTestLocation()); 1033 HitTestResult tempResult(result.hitTestLocation());
1017 if (hitTestContents(request, tempResult, layerBounds, hitTestLocation) 1034 if (hitTestContents(request, tempResult, layerBounds, localHitTestLocati on)
1018 && isHitCandidate(this, false, zOffsetForContentsPtr, unflattenedTra nsformState.get())) { 1035 && isHitCandidate(this, false, zOffsetForContentsPtr, unflattenedTra nsformState.get())) {
1019 if (result.isRectBasedTest()) 1036 if (result.isRectBasedTest())
1020 result.append(tempResult); 1037 result.append(tempResult);
1021 else 1038 else
1022 result = tempResult; 1039 result = tempResult;
1023 if (!depthSortDescendants) 1040 if (!depthSortDescendants)
1024 return this; 1041 return this;
1025 // Foreground can depth-sort with descendant layers, so keep this as a candidate. 1042 // Foreground can depth-sort with descendant layers, so keep this as a candidate.
1026 candidateLayer = this; 1043 candidateLayer = this;
1027 } else if (result.isRectBasedTest()) { 1044 } else if (result.isRectBasedTest()) {
1028 result.append(tempResult); 1045 result.append(tempResult);
1029 } 1046 }
1030 } 1047 }
1031 1048
1032 return candidateLayer; 1049 return candidateLayer;
1033 } 1050 }
1034 1051
1035 RenderLayer* RenderLayer::hitTestLayerByApplyingTransform(RenderLayer* rootLayer , RenderLayer* containerLayer, const HitTestRequest& request, HitTestResult& res ult,
1036 const LayoutRect& hitTestRect, const HitTestLocation& hitTestLocation, const HitTestingTransformState* transformState, double* zOffset,
1037 const LayoutPoint& translationOffset)
1038 {
1039 // Create a transform state to accumulate this transform.
1040 RefPtr<HitTestingTransformState> newTransformState = createLocalTransformSta te(rootLayer, containerLayer, hitTestRect, hitTestLocation, transformState, tran slationOffset);
1041
1042 // If the transform can't be inverted, then don't hit test this layer at all .
1043 if (!newTransformState->m_accumulatedTransform.isInvertible())
1044 return 0;
1045
1046 // Compute the point and the hit test rect in the coords of this layer by us ing the values
1047 // from the transformState, which store the point and quad in the coords of the last flattened
1048 // layer, and the accumulated transform which lets up map through preserve-3 d layers.
1049 //
1050 // We can't just map hitTestLocation and hitTestRect because they may have b een flattened (losing z)
1051 // by our container.
1052 FloatPoint localPoint = newTransformState->mappedPoint();
1053 FloatQuad localPointQuad = newTransformState->mappedQuad();
1054 LayoutRect localHitTestRect = newTransformState->boundsOfMappedArea();
1055 HitTestLocation newHitTestLocation;
1056 if (hitTestLocation.isRectBasedTest())
1057 newHitTestLocation = HitTestLocation(localPoint, localPointQuad);
1058 else
1059 newHitTestLocation = HitTestLocation(localPoint);
1060
1061 // Now do a hit test with the root layer shifted to be us.
1062 return hitTestLayer(this, containerLayer, request, result, localHitTestRect, newHitTestLocation, true, newTransformState.get(), zOffset);
1063 }
1064
1065 bool RenderLayer::hitTestContents(const HitTestRequest& request, HitTestResult& result, const LayoutRect& layerBounds, const HitTestLocation& hitTestLocation) c onst 1052 bool RenderLayer::hitTestContents(const HitTestRequest& request, HitTestResult& result, const LayoutRect& layerBounds, const HitTestLocation& hitTestLocation) c onst
1066 { 1053 {
1067 ASSERT(isSelfPaintingLayer() || hasSelfPaintingLayerDescendant()); 1054 ASSERT(isSelfPaintingLayer() || hasSelfPaintingLayerDescendant());
1068 1055
1069 if (!renderer()->hitTest(request, result, hitTestLocation, toLayoutPoint(lay erBounds.location() - renderBoxLocation()))) { 1056 if (!renderer()->hitTest(request, result, hitTestLocation, toLayoutPoint(lay erBounds.location() - renderBoxLocation()))) {
1070 // It's wrong to set innerNode, but then claim that you didn't hit anyth ing, unless it is 1057 // It's wrong to set innerNode, but then claim that you didn't hit anyth ing, unless it is
1071 // a rect-based test. 1058 // a rect-based test.
1072 ASSERT(!result.innerNode() || (result.isRectBasedTest() && result.rectBa sedTestResult().size())); 1059 ASSERT(!result.innerNode() || (result.isRectBasedTest() && result.rectBa sedTestResult().size()));
1073 return false; 1060 return false;
1074 } 1061 }
(...skipping 23 matching lines...) Expand all
1098 { 1085 {
1099 if (!hasSelfPaintingLayerDescendant()) 1086 if (!hasSelfPaintingLayerDescendant())
1100 return 0; 1087 return 0;
1101 1088
1102 RenderLayer* resultLayer = 0; 1089 RenderLayer* resultLayer = 0;
1103 RenderLayerStackingNodeReverseIterator iterator(*m_stackingNode, childrentoV isit); 1090 RenderLayerStackingNodeReverseIterator iterator(*m_stackingNode, childrentoV isit);
1104 while (RenderLayerStackingNode* child = iterator.next()) { 1091 while (RenderLayerStackingNode* child = iterator.next()) {
1105 RenderLayer* childLayer = child->layer(); 1092 RenderLayer* childLayer = child->layer();
1106 RenderLayer* hitLayer = 0; 1093 RenderLayer* hitLayer = 0;
1107 HitTestResult tempResult(result.hitTestLocation()); 1094 HitTestResult tempResult(result.hitTestLocation());
1108 hitLayer = childLayer->hitTestLayer(rootLayer, this, request, tempResult , hitTestRect, hitTestLocation, false, transformState, zOffsetForDescendants); 1095 hitLayer = childLayer->hitTestLayer(rootLayer, this, request, tempResult , hitTestRect, hitTestLocation, transformState, zOffsetForDescendants);
1109 1096
1110 // If it a rect-based test, we can safely append the temporary result si nce it might had hit 1097 // If it a rect-based test, we can safely append the temporary result si nce it might had hit
1111 // nodes but not necesserily had hitLayer set. 1098 // nodes but not necesserily had hitLayer set.
1112 if (result.isRectBasedTest()) 1099 if (result.isRectBasedTest())
1113 result.append(tempResult); 1100 result.append(tempResult);
1114 1101
1115 if (isHitCandidate(hitLayer, depthSortDescendants, zOffset, unflattenedT ransformState)) { 1102 if (isHitCandidate(hitLayer, depthSortDescendants, zOffset, unflattenedT ransformState)) {
1116 resultLayer = hitLayer; 1103 resultLayer = hitLayer;
1117 if (!result.isRectBasedTest()) 1104 if (!result.isRectBasedTest())
1118 result = tempResult; 1105 result = tempResult;
(...skipping 285 matching lines...) Expand 10 before | Expand all | Expand 10 after
1404 } 1391 }
1405 } 1392 }
1406 1393
1407 void showLayerTree(const blink::RenderObject* renderer) 1394 void showLayerTree(const blink::RenderObject* renderer)
1408 { 1395 {
1409 if (!renderer) 1396 if (!renderer)
1410 return; 1397 return;
1411 showLayerTree(renderer->enclosingLayer()); 1398 showLayerTree(renderer->enclosingLayer());
1412 } 1399 }
1413 #endif 1400 #endif
OLDNEW
« no previous file with comments | « sky/engine/core/rendering/RenderLayer.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698