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

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

Issue 939793003: Change the return value of RenderLayer::hitTestLayer. (Closed) Base URL: git@github.com:domokit/mojo.git@master
Patch Set: fix indentation 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') | sky/engine/core/rendering/RenderView.cpp » ('j') | 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 829 matching lines...) Expand 10 before | Expand all | Expand 10 after
840 renderer()->getTransformFromContainer(containerRenderer, toLayoutSize(of fset), containerTransform); 840 renderer()->getTransformFromContainer(containerRenderer, toLayoutSize(of fset), containerTransform);
841 transformState->applyTransform(containerTransform, HitTestingTransformSt ate::AccumulateTransform); 841 transformState->applyTransform(containerTransform, HitTestingTransformSt ate::AccumulateTransform);
842 } else { 842 } else {
843 transformState->translate(offset.x(), offset.y(), HitTestingTransformSta te::AccumulateTransform); 843 transformState->translate(offset.x(), offset.y(), HitTestingTransformSta te::AccumulateTransform);
844 } 844 }
845 845
846 return transformState; 846 return transformState;
847 } 847 }
848 848
849 849
850 static bool isHitCandidate(const RenderLayer* hitLayer, bool canDepthSort, doubl e* zOffset, const HitTestingTransformState* transformState) 850 static bool isHitCandidate(bool canDepthSort, double* zOffset, const HitTestingT ransformState* transformState)
851 { 851 {
852 if (!hitLayer)
853 return false;
854
855 // The hit layer is depth-sorting with other layers, so just say that it was hit. 852 // The hit layer is depth-sorting with other layers, so just say that it was hit.
856 if (canDepthSort) 853 if (canDepthSort)
857 return true; 854 return true;
858 855
859 // We need to look at z-depth to decide if this layer was hit. 856 // We need to look at z-depth to decide if this layer was hit.
860 if (zOffset) { 857 if (zOffset) {
861 ASSERT(transformState); 858 ASSERT(transformState);
862 // This is actually computing our z, but that's OK because the hitLayer is coplanar with us. 859 // This is actually computing our z, but that's OK because the hitLayer is coplanar with us.
863 double childZOffset = computeZOffset(*transformState); 860 double childZOffset = computeZOffset(*transformState);
864 if (childZOffset > *zOffset) { 861 if (childZOffset > *zOffset) {
865 *zOffset = childZOffset; 862 *zOffset = childZOffset;
866 return true; 863 return true;
867 } 864 }
868 return false; 865 return false;
869 } 866 }
870 867
871 return true; 868 return true;
872 } 869 }
873 870
874 // hitTestLocation and hitTestRect are relative to rootLayer. 871 // hitTestLocation and hitTestRect are relative to rootLayer.
875 // A 'flattening' layer is one preserves3D() == false. 872 // A 'flattening' layer is one preserves3D() == false.
876 // transformState.m_accumulatedTransform holds the transform from the containing flattening layer. 873 // transformState.m_accumulatedTransform holds the transform from the containing flattening layer.
877 // transformState.m_lastPlanarPoint is the hitTestLocation in the plane of the c ontaining flattening layer. 874 // transformState.m_lastPlanarPoint is the hitTestLocation in the plane of the c ontaining flattening layer.
878 // transformState.m_lastPlanarQuad is the hitTestRect as a quad in the plane of the containing flattening layer. 875 // transformState.m_lastPlanarQuad is the hitTestRect as a quad in the plane of the containing flattening layer.
879 // 876 //
880 // If zOffset is non-null (which indicates that the caller wants z offset inform ation), 877 // If zOffset is non-null (which indicates that the caller wants z offset inform ation),
881 // *zOffset on return is the z offset of the hit point relative to the containi ng flattening layer. 878 // *zOffset on return is the z offset of the hit point relative to the containi ng flattening layer.
882 RenderLayer* RenderLayer::hitTestLayer(RenderLayer* rootLayer, RenderLayer* cont ainerLayer, const HitTestRequest& request, HitTestResult& result, 879 bool RenderLayer::hitTestLayer(RenderLayer* rootLayer, RenderLayer* containerLay er, const HitTestRequest& request, HitTestResult& result,
883 const LayoutRect& hitTestRect, const HitT estLocation& hitTestLocation, 880 const LayoutRect& hitTestRect, const HitT estLocation& hitTestLocation,
884 const HitTestingTransformState* transform State, double* zOffset) 881 const HitTestingTransformState* transform State, double* zOffset)
885 { 882 {
886 if (!isSelfPaintingLayer() && !hasSelfPaintingLayerDescendant()) 883 if (!isSelfPaintingLayer() && !hasSelfPaintingLayerDescendant())
887 return 0; 884 return 0;
888 885
889 // The natural thing would be to keep HitTestingTransformState on the stack, but it's big, so we heap-allocate. 886 // The natural thing would be to keep HitTestingTransformState on the stack, but it's big, so we heap-allocate.
890 RefPtr<HitTestingTransformState> localTransformState; 887 RefPtr<HitTestingTransformState> localTransformState;
891 888
892 LayoutRect localHitTestRect = hitTestRect; 889 LayoutRect localHitTestRect = hitTestRect;
(...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after
959 depthSortDescendants = true; 956 depthSortDescendants = true;
960 // Our layers can depth-test with our container, so share the z depth po inter with the container, if it passed one down. 957 // Our layers can depth-test with our container, so share the z depth po inter with the container, if it passed one down.
961 zOffsetForDescendantsPtr = zOffset ? zOffset : &localZOffset; 958 zOffsetForDescendantsPtr = zOffset ? zOffset : &localZOffset;
962 zOffsetForContentsPtr = zOffset ? zOffset : &localZOffset; 959 zOffsetForContentsPtr = zOffset ? zOffset : &localZOffset;
963 } else if (zOffset) { 960 } else if (zOffset) {
964 zOffsetForDescendantsPtr = 0; 961 zOffsetForDescendantsPtr = 0;
965 // Container needs us to give back a z offset for the hit layer. 962 // Container needs us to give back a z offset for the hit layer.
966 zOffsetForContentsPtr = zOffset; 963 zOffsetForContentsPtr = zOffset;
967 } 964 }
968 965
969 // This variable tracks which layer the mouse ends up being inside.
970 RenderLayer* candidateLayer = 0;
971
972 // Begin by walking our list of positive layers from highest z-index down to the lowest z-index. 966 // Begin by walking our list of positive layers from highest z-index down to the lowest z-index.
973 RenderLayer* hitLayer = hitTestChildren(PositiveZOrderChildren, rootLayer, r equest, result, localHitTestRect, localHitTestLocation, 967 bool hitLayer = hitTestChildren(PositiveZOrderChildren, rootLayer, request, result, localHitTestRect, localHitTestLocation,
974 localTransformState.get(), zOffsetForDes cendantsPtr, zOffset, unflattenedTransformState.get(), depthSortDescendants); 968 localTransformState.get(), zOffsetForDescend antsPtr, zOffset, unflattenedTransformState.get(), depthSortDescendants);
975 if (hitLayer) { 969 if (hitLayer && !depthSortDescendants)
976 if (!depthSortDescendants) 970 return true;
977 return hitLayer;
978 candidateLayer = hitLayer;
979 }
980 971
981 // Now check our overflow objects. 972 // Now check our overflow objects.
982 hitLayer = hitTestChildren(NormalFlowChildren, rootLayer, request, result, l ocalHitTestRect, localHitTestLocation, 973 hitLayer = hitTestChildren(NormalFlowChildren, rootLayer, request, result, l ocalHitTestRect, localHitTestLocation,
983 localTransformState.get(), zOffsetForDescendantsPtr, zOffset, unflattenedTransformState.get(), depthSortDescendants); 974 localTransformState.get(), zOffsetForDescendantsP tr, zOffset, unflattenedTransformState.get(), depthSortDescendants);
984 if (hitLayer) { 975 if (hitLayer && !depthSortDescendants)
985 if (!depthSortDescendants) 976 return true;
986 return hitLayer;
987 candidateLayer = hitLayer;
988 }
989 977
990 LayoutRect layerBounds; 978 LayoutRect layerBounds;
991 // FIXME(sky): Remove foregroundRect. It's unused. 979 // FIXME(sky): Remove foregroundRect. It's unused.
992 ClipRect contentRect, foregroundRect; 980 ClipRect contentRect, foregroundRect;
993 ClipRectsContext clipRectsContext(rootLayer, RootRelativeClipRects); 981 ClipRectsContext clipRectsContext(rootLayer, RootRelativeClipRects);
994 clipper().calculateRects(clipRectsContext, localHitTestRect, layerBounds, co ntentRect, foregroundRect); 982 clipper().calculateRects(clipRectsContext, localHitTestRect, layerBounds, co ntentRect, foregroundRect);
995 983
996 // Next we want to see if the mouse pos is inside the child RenderObjects of the layer. 984 // Next we want to see if the mouse pos is inside the child RenderObjects of the layer.
997 if (isSelfPaintingLayer() && contentRect.intersects(localHitTestLocation)) { 985 if (isSelfPaintingLayer() && contentRect.intersects(localHitTestLocation)) {
998 // Hit test with a temporary HitTestResult, because we only want to comm it to 'result' if we know we're frontmost. 986 // Hit test with a temporary HitTestResult, because we only want to comm it to 'result' if we know we're frontmost.
999 HitTestResult tempResult(result.hitTestLocation()); 987 HitTestResult tempResult(result.hitTestLocation());
1000 if (hitTestContents(request, tempResult, layerBounds, localHitTestLocati on) 988 if (hitTestContents(request, tempResult, layerBounds, localHitTestLocati on)
1001 && isHitCandidate(this, false, zOffsetForContentsPtr, unflattenedTra nsformState.get())) { 989 && isHitCandidate(false, zOffsetForContentsPtr, unflattenedTransform State.get())) {
1002 if (result.isRectBasedTest()) 990 if (result.isRectBasedTest())
1003 result.append(tempResult); 991 result.append(tempResult);
1004 else 992 else
1005 result = tempResult; 993 result = tempResult;
1006 if (!depthSortDescendants) 994 if (!depthSortDescendants)
1007 return this; 995 return true;
1008 // Foreground can depth-sort with descendant layers, so keep this as a candidate. 996 // Foreground can depth-sort with descendant layers, so keep this as a candidate.
1009 candidateLayer = this; 997 hitLayer = true;
1010 } else if (result.isRectBasedTest()) { 998 } else if (result.isRectBasedTest()) {
1011 result.append(tempResult); 999 result.append(tempResult);
1012 } 1000 }
1013 } 1001 }
1014 1002
1015 return candidateLayer; 1003 return hitLayer;
1016 } 1004 }
1017 1005
1018 bool RenderLayer::hitTestContents(const HitTestRequest& request, HitTestResult& result, const LayoutRect& layerBounds, const HitTestLocation& hitTestLocation) c onst 1006 bool RenderLayer::hitTestContents(const HitTestRequest& request, HitTestResult& result, const LayoutRect& layerBounds, const HitTestLocation& hitTestLocation) c onst
1019 { 1007 {
1020 ASSERT(isSelfPaintingLayer() || hasSelfPaintingLayerDescendant()); 1008 ASSERT(isSelfPaintingLayer() || hasSelfPaintingLayerDescendant());
1021 1009
1022 if (!renderer()->hitTest(request, result, hitTestLocation, toLayoutPoint(lay erBounds.location() - renderBoxLocation()))) { 1010 if (!renderer()->hitTest(request, result, hitTestLocation, toLayoutPoint(lay erBounds.location() - renderBoxLocation()))) {
1023 // It's wrong to set innerNode, but then claim that you didn't hit anyth ing, unless it is 1011 // It's wrong to set innerNode, but then claim that you didn't hit anyth ing, unless it is
1024 // a rect-based test. 1012 // a rect-based test.
1025 ASSERT(!result.innerNode() || (result.isRectBasedTest() && result.rectBa sedTestResult().size())); 1013 ASSERT(!result.innerNode() || (result.isRectBasedTest() && result.rectBa sedTestResult().size()));
1026 return false; 1014 return false;
1027 } 1015 }
1028 1016
1029 // For positioned generated content, we might still not have a 1017 // For positioned generated content, we might still not have a
1030 // node by the time we get to the layer level, since none of 1018 // node by the time we get to the layer level, since none of
1031 // the content in the layer has an element. So just walk up 1019 // the content in the layer has an element. So just walk up
1032 // the tree. 1020 // the tree.
1033 if (!result.innerNode() || !result.innerNonSharedNode()) { 1021 if (!result.innerNode() || !result.innerNonSharedNode()) {
1034 Node* e = enclosingElement(); 1022 Node* e = enclosingElement();
1035 if (!result.innerNode()) 1023 if (!result.innerNode())
1036 result.setInnerNode(e); 1024 result.setInnerNode(e);
1037 if (!result.innerNonSharedNode()) 1025 if (!result.innerNonSharedNode())
1038 result.setInnerNonSharedNode(e); 1026 result.setInnerNonSharedNode(e);
1039 } 1027 }
1040 1028
1041 return true; 1029 return true;
1042 } 1030 }
1043 1031
1044 RenderLayer* RenderLayer::hitTestChildren(ChildrenIteration childrentoVisit, Ren derLayer* rootLayer, 1032 bool RenderLayer::hitTestChildren(ChildrenIteration childrentoVisit, RenderLayer * rootLayer,
1045 const HitTestRequest& request, HitTestResult& result, 1033 const HitTestRequest& request, HitTestResult& result,
1046 const LayoutRect& hitTestRect, const HitTestLocation& hitTestLocation, 1034 const LayoutRect& hitTestRect, const HitTestLocation& hitTestLocation,
1047 const HitTestingTransformState* transformState, 1035 const HitTestingTransformState* transformState,
1048 double* zOffsetForDescendants, double* zOffset, 1036 double* zOffsetForDescendants, double* zOffset,
1049 const HitTestingTransformState* unflattenedTransformState, 1037 const HitTestingTransformState* unflattenedTransformState,
1050 bool depthSortDescendants) 1038 bool depthSortDescendants)
1051 { 1039 {
1052 if (!hasSelfPaintingLayerDescendant()) 1040 if (!hasSelfPaintingLayerDescendant())
1053 return 0; 1041 return 0;
1054 1042
1055 RenderLayer* resultLayer = 0; 1043 bool hitLayer = false;
1056 RenderLayerStackingNodeReverseIterator iterator(*m_stackingNode, childrentoV isit); 1044 RenderLayerStackingNodeReverseIterator iterator(*m_stackingNode, childrentoV isit);
1057 while (RenderLayerStackingNode* child = iterator.next()) { 1045 while (RenderLayerStackingNode* child = iterator.next()) {
1058 RenderLayer* childLayer = child->layer(); 1046 RenderLayer* childLayer = child->layer();
1059 RenderLayer* hitLayer = 0;
1060 HitTestResult tempResult(result.hitTestLocation()); 1047 HitTestResult tempResult(result.hitTestLocation());
1061 hitLayer = childLayer->hitTestLayer(rootLayer, this, request, tempResult , hitTestRect, hitTestLocation, transformState, zOffsetForDescendants); 1048 hitLayer |= childLayer->hitTestLayer(rootLayer, this, request, tempResul t, hitTestRect, hitTestLocation, transformState, zOffsetForDescendants);
1062 1049
1063 // If it a rect-based test, we can safely append the temporary result si nce it might had hit 1050 // If it a rect-based test, we can safely append the temporary result si nce it might had hit
1064 // nodes but not necesserily had hitLayer set. 1051 // nodes but not necesserily had hitLayer set.
1065 if (result.isRectBasedTest()) 1052 if (result.isRectBasedTest())
1066 result.append(tempResult); 1053 result.append(tempResult);
1067 1054
1068 if (isHitCandidate(hitLayer, depthSortDescendants, zOffset, unflattenedT ransformState)) { 1055 if (hitLayer && isHitCandidate(depthSortDescendants, zOffset, unflattene dTransformState)) {
1069 resultLayer = hitLayer;
1070 if (!result.isRectBasedTest()) 1056 if (!result.isRectBasedTest())
1071 result = tempResult; 1057 result = tempResult;
1072 if (!depthSortDescendants) 1058 if (!depthSortDescendants)
1073 break; 1059 break;
1074 } 1060 }
1075 } 1061 }
1076 1062
1077 return resultLayer; 1063 return hitLayer;
1078 } 1064 }
1079 1065
1080 bool RenderLayer::intersectsDamageRect(const LayoutRect& layerBounds, const Layo utRect& damageRect, const RenderLayer* rootLayer, const LayoutPoint* offsetFromR oot) const 1066 bool RenderLayer::intersectsDamageRect(const LayoutRect& layerBounds, const Layo utRect& damageRect, const RenderLayer* rootLayer, const LayoutPoint* offsetFromR oot) const
1081 { 1067 {
1082 // Always examine the canvas and the root. 1068 // Always examine the canvas and the root.
1083 if (isRootLayer()) 1069 if (isRootLayer())
1084 return true; 1070 return true;
1085 1071
1086 // If we aren't an inline flow, and our layer bounds do intersect the damage rect, then we 1072 // If we aren't an inline flow, and our layer bounds do intersect the damage rect, then we
1087 // can go ahead and return true. 1073 // can go ahead and return true.
(...skipping 269 matching lines...) Expand 10 before | Expand all | Expand 10 after
1357 } 1343 }
1358 } 1344 }
1359 1345
1360 void showLayerTree(const blink::RenderObject* renderer) 1346 void showLayerTree(const blink::RenderObject* renderer)
1361 { 1347 {
1362 if (!renderer) 1348 if (!renderer)
1363 return; 1349 return;
1364 showLayerTree(renderer->enclosingLayer()); 1350 showLayerTree(renderer->enclosingLayer());
1365 } 1351 }
1366 #endif 1352 #endif
OLDNEW
« no previous file with comments | « sky/engine/core/rendering/RenderLayer.h ('k') | sky/engine/core/rendering/RenderView.cpp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698