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

Side by Side Diff: Source/core/paint/DeprecatedPaintLayer.cpp

Issue 1142283004: Implement a Hit Test Cache. (Closed) Base URL: https://chromium.googlesource.com/chromium/blink.git@master
Patch Set: Created 5 years, 7 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
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 1642 matching lines...) Expand 10 before | Expand all | Expand 10 after
1653 { 1653 {
1654 FrameView* frameView = layoutObject->document().view(); 1654 FrameView* frameView = layoutObject->document().view();
1655 if (!frameView) 1655 if (!frameView)
1656 return LayoutRect(); 1656 return LayoutRect();
1657 1657
1658 return LayoutRect(frameView->visibleContentRect()); 1658 return LayoutRect(frameView->visibleContentRect());
1659 } 1659 }
1660 1660
1661 bool DeprecatedPaintLayer::hitTest(HitTestResult& result) 1661 bool DeprecatedPaintLayer::hitTest(HitTestResult& result)
1662 { 1662 {
1663 return hitTest(result.hitTestRequest(), result.hitTestLocation(), result);
1664 }
1665
1666 bool DeprecatedPaintLayer::hitTest(const HitTestRequest& request, const HitTestL ocation& hitTestLocation, HitTestResult& result)
1667 {
1668 ASSERT(isSelfPaintingLayer() || hasSelfPaintingLayerDescendant()); 1663 ASSERT(isSelfPaintingLayer() || hasSelfPaintingLayerDescendant());
1669 1664
1670 // LayoutView should make sure to update layout before entering hit testing 1665 // LayoutView should make sure to update layout before entering hit testing
1671 ASSERT(!layoutObject()->frame()->view()->layoutPending()); 1666 ASSERT(!layoutObject()->frame()->view()->layoutPending());
1672 ASSERT(!layoutObject()->document().layoutView()->needsLayout()); 1667 ASSERT(!layoutObject()->document().layoutView()->needsLayout());
1673 1668
1669 const HitTestRequest& request = result.hitTestRequest();
1670 const HitTestLocation& hitTestLocation = result.hitTestLocation();
1671
1674 // Start with frameVisibleRect to ensure we include the scrollbars. 1672 // Start with frameVisibleRect to ensure we include the scrollbars.
1675 LayoutRect hitTestArea = frameVisibleRect(layoutObject()); 1673 LayoutRect hitTestArea = frameVisibleRect(layoutObject());
1676 if (request.ignoreClipping()) 1674 if (request.ignoreClipping())
1677 hitTestArea.unite(LayoutRect(layoutObject()->view()->documentRect())); 1675 hitTestArea.unite(LayoutRect(layoutObject()->view()->documentRect()));
1676 result.setValidityRect(hitTestArea);
1678 1677
1679 DeprecatedPaintLayer* insideLayer = hitTestLayer(this, 0, result, hitTestAre a, hitTestLocation, false); 1678 DeprecatedPaintLayer* insideLayer = hitTestLayer(this, 0, result, hitTestAre a, result.hitTestLocation(), false);
1680 if (!insideLayer) { 1679 if (!insideLayer) {
1681 // We didn't hit any layer. If we are the root layer and the mouse is -- or just was -- down, 1680 // We didn't hit any layer. If we are the root layer and the mouse is -- or just was -- down,
1682 // return ourselves. We do this so mouse events continue getting deliver ed after a drag has 1681 // return ourselves. We do this so mouse events continue getting deliver ed after a drag has
1683 // exited the WebView, and so hit testing over a scrollbar hits the cont ent document. 1682 // exited the WebView, and so hit testing over a scrollbar hits the cont ent document.
1684 // In addtion, it is possible for the mouse to stay in the document but there is no element. 1683 // In addtion, it is possible for the mouse to stay in the document but there is no element.
1685 // At that time, the events of the mouse should be fired. 1684 // At that time, the events of the mouse should be fired.
1686 LayoutPoint hitPoint = hitTestLocation.point(); 1685 LayoutPoint hitPoint = hitTestLocation.point();
1687 if (!request.isChildFrameHitTest() && ((request.active() || request.rele ase()) || (request.move() && hitTestArea.contains(hitPoint.x(), hitPoint.y()))) && isRootLayer()) { 1686 if (!request.isChildFrameHitTest() && ((request.active() || request.rele ase()) || (request.move() && hitTestArea.contains(hitPoint.x(), hitPoint.y()))) && isRootLayer()) {
1688 layoutObject()->updateHitTestResult(result, toLayoutView(layoutObjec t())->flipForWritingMode(hitTestLocation.point())); 1687 layoutObject()->updateHitTestResult(result, toLayoutView(layoutObjec t())->flipForWritingMode(hitTestLocation.point()), LayoutRect(hitTestLocation.po int(), LayoutSize(IntSize(1, 1))));
1689 insideLayer = this; 1688 insideLayer = this;
1690 } 1689 }
1691 } 1690 }
1692 1691
1693 // Now determine if the result is inside an anchor - if the urlElement isn't already set. 1692 // Now determine if the result is inside an anchor - if the urlElement isn't already set.
1694 Node* node = result.innerNode(); 1693 Node* node = result.innerNode();
1695 if (node && !result.URLElement()) 1694 if (node && !result.URLElement())
1696 result.setURLElement(node->enclosingLinkEventParentOrSelf()); 1695 result.setURLElement(node->enclosingLinkEventParentOrSelf());
1697 1696
1698 // Now return whether we were inside this layer (this will always be true fo r the root 1697 // Now return whether we were inside this layer (this will always be true fo r the root
(...skipping 195 matching lines...) Expand 10 before | Expand all | Expand 10 after
1894 } 1893 }
1895 1894
1896 // Collect the fragments. This will compute the clip rectangles for each lay er fragment. 1895 // Collect the fragments. This will compute the clip rectangles for each lay er fragment.
1897 DeprecatedPaintLayerFragments layerFragments; 1896 DeprecatedPaintLayerFragments layerFragments;
1898 if (appliedTransform) 1897 if (appliedTransform)
1899 appendSingleFragmentIgnoringPagination(layerFragments, rootLayer, hitTes tRect, RootRelativeClipRects, IncludeOverlayScrollbarSize); 1898 appendSingleFragmentIgnoringPagination(layerFragments, rootLayer, hitTes tRect, RootRelativeClipRects, IncludeOverlayScrollbarSize);
1900 else 1899 else
1901 collectFragments(layerFragments, rootLayer, hitTestRect, RootRelativeCli pRects, IncludeOverlayScrollbarSize); 1900 collectFragments(layerFragments, rootLayer, hitTestRect, RootRelativeCli pRects, IncludeOverlayScrollbarSize);
1902 1901
1903 if (m_scrollableArea && m_scrollableArea->hitTestResizerInFragments(layerFra gments, hitTestLocation)) { 1902 if (m_scrollableArea && m_scrollableArea->hitTestResizerInFragments(layerFra gments, hitTestLocation)) {
1904 layoutObject()->updateHitTestResult(result, hitTestLocation.point()); 1903 layoutObject()->updateHitTestResult(result, hitTestLocation.point(), bou ndingRect(hitTestLocation.point()));
1905 return this; 1904 return this;
1906 } 1905 }
1907 1906
1908 // Next we want to see if the mouse pos is inside the child LayoutObjects of the layer. Check 1907 // Next we want to see if the mouse pos is inside the child LayoutObjects of the layer. Check
1909 // every fragment in reverse order. 1908 // every fragment in reverse order.
1910 if (isSelfPaintingLayer()) { 1909 if (isSelfPaintingLayer()) {
1911 // Hit test with a temporary HitTestResult, because we only want to comm it to 'result' if we know we're frontmost. 1910 // Hit test with a temporary HitTestResult, because we only want to comm it to 'result' if we know we're frontmost.
1912 HitTestResult tempResult(result.hitTestRequest(), result.hitTestLocation ()); 1911 HitTestResult tempResult(result.hitTestRequest(), result.hitTestLocation ());
1912 tempResult.setValidityRect(result.validityRect());
1913 bool insideFragmentForegroundRect = false; 1913 bool insideFragmentForegroundRect = false;
1914 if (hitTestContentsForFragments(layerFragments, tempResult, hitTestLocat ion, HitTestDescendants, insideFragmentForegroundRect) 1914 if (hitTestContentsForFragments(layerFragments, tempResult, hitTestLocat ion, HitTestDescendants, insideFragmentForegroundRect)
1915 && isHitCandidate(this, false, zOffsetForContentsPtr, unflattenedTra nsformState.get())) { 1915 && isHitCandidate(this, false, zOffsetForContentsPtr, unflattenedTra nsformState.get())) {
1916 if (result.hitTestRequest().listBased()) 1916 if (result.hitTestRequest().listBased())
1917 result.append(tempResult); 1917 result.append(tempResult);
1918 else 1918 else
1919 result = tempResult; 1919 result = tempResult;
1920 if (!depthSortDescendants) 1920 if (!depthSortDescendants)
1921 return this; 1921 return this;
1922 // Foreground can depth-sort with descendant layers, so keep this as a candidate. 1922 // Foreground can depth-sort with descendant layers, so keep this as a candidate.
1923 candidateLayer = this; 1923 candidateLayer = this;
1924 } else if (insideFragmentForegroundRect && result.hitTestRequest().listB ased()) { 1924 } else if (insideFragmentForegroundRect && result.hitTestRequest().listB ased()) {
1925 result.append(tempResult); 1925 result.append(tempResult);
1926 } else {
1927 result.setValidityRect(result.validityRect());
1926 } 1928 }
1927 } 1929 }
1928 1930
1929 // Now check our negative z-index children. 1931 // Now check our negative z-index children.
1930 hitLayer = hitTestChildren(NegativeZOrderChildren, rootLayer, result, hitTes tRect, hitTestLocation, 1932 hitLayer = hitTestChildren(NegativeZOrderChildren, rootLayer, result, hitTes tRect, hitTestLocation,
1931 localTransformState.get(), zOffsetForDescendantsPtr, zOffset, unflattene dTransformState.get(), depthSortDescendants); 1933 localTransformState.get(), zOffsetForDescendantsPtr, zOffset, unflattene dTransformState.get(), depthSortDescendants);
1932 if (hitLayer) { 1934 if (hitLayer) {
1933 if (!depthSortDescendants) 1935 if (!depthSortDescendants)
1934 return hitLayer; 1936 return hitLayer;
1935 candidateLayer = hitLayer; 1937 candidateLayer = hitLayer;
1936 } 1938 }
1937 1939
1938 // If we found a layer, return. Child layers, and foreground always render i n front of background. 1940 // If we found a layer, return. Child layers, and foreground always render i n front of background.
1939 if (candidateLayer) 1941 if (candidateLayer)
1940 return candidateLayer; 1942 return candidateLayer;
1941 1943
1942 if (isSelfPaintingLayer()) { 1944 if (isSelfPaintingLayer()) {
1943 HitTestResult tempResult(result.hitTestRequest(), result.hitTestLocation ()); 1945 HitTestResult tempResult(result.hitTestRequest(), result.hitTestLocation ());
1946 tempResult.setValidityRect(result.validityRect());
1944 bool insideFragmentBackgroundRect = false; 1947 bool insideFragmentBackgroundRect = false;
1945 if (hitTestContentsForFragments(layerFragments, tempResult, hitTestLocat ion, HitTestSelf, insideFragmentBackgroundRect) 1948 if (hitTestContentsForFragments(layerFragments, tempResult, hitTestLocat ion, HitTestSelf, insideFragmentBackgroundRect)
1946 && isHitCandidate(this, false, zOffsetForContentsPtr, unflattenedTra nsformState.get())) { 1949 && isHitCandidate(this, false, zOffsetForContentsPtr, unflattenedTra nsformState.get())) {
1947 if (result.isRectBasedTest()) 1950 if (result.isRectBasedTest())
1948 result.append(tempResult); 1951 result.append(tempResult);
1949 else 1952 else
1950 result = tempResult; 1953 result = tempResult;
1951 return this; 1954 return this;
1955 } else if (insideFragmentBackgroundRect && result.hitTestRequest().listB ased()) {
1956 result.append(tempResult);
1957 } else {
1958 result.setValidityRect(tempResult.validityRect());
1952 } 1959 }
1953 if (insideFragmentBackgroundRect && result.hitTestRequest().listBased())
1954 result.append(tempResult);
1955 } 1960 }
1956 1961
1957 return 0; 1962 return 0;
1958 } 1963 }
1959 1964
1960 bool DeprecatedPaintLayer::hitTestContentsForFragments(const DeprecatedPaintLaye rFragments& layerFragments, HitTestResult& result, 1965 bool DeprecatedPaintLayer::hitTestContentsForFragments(const DeprecatedPaintLaye rFragments& layerFragments, HitTestResult& result,
1961 const HitTestLocation& hitTestLocation, HitTestFilter hitTestFilter, bool& i nsideClipRect) const 1966 const HitTestLocation& hitTestLocation, HitTestFilter hitTestFilter, bool& i nsideClipRect) const
1962 { 1967 {
1963 if (layerFragments.isEmpty()) 1968 if (layerFragments.isEmpty())
1964 return false; 1969 return false;
(...skipping 123 matching lines...) Expand 10 before | Expand all | Expand 10 after
2088 { 2093 {
2089 if (!hasSelfPaintingLayerDescendant()) 2094 if (!hasSelfPaintingLayerDescendant())
2090 return 0; 2095 return 0;
2091 2096
2092 DeprecatedPaintLayer* resultLayer = 0; 2097 DeprecatedPaintLayer* resultLayer = 0;
2093 DeprecatedPaintLayerStackingNodeReverseIterator iterator(*m_stackingNode, ch ildrentoVisit); 2098 DeprecatedPaintLayerStackingNodeReverseIterator iterator(*m_stackingNode, ch ildrentoVisit);
2094 while (DeprecatedPaintLayerStackingNode* child = iterator.next()) { 2099 while (DeprecatedPaintLayerStackingNode* child = iterator.next()) {
2095 DeprecatedPaintLayer* childLayer = child->layer(); 2100 DeprecatedPaintLayer* childLayer = child->layer();
2096 DeprecatedPaintLayer* hitLayer = 0; 2101 DeprecatedPaintLayer* hitLayer = 0;
2097 HitTestResult tempResult(result.hitTestRequest(), result.hitTestLocation ()); 2102 HitTestResult tempResult(result.hitTestRequest(), result.hitTestLocation ());
2103 tempResult.setValidityRect(result.validityRect());
2098 if (childLayer->isPaginated()) 2104 if (childLayer->isPaginated())
2099 hitLayer = hitTestPaginatedChildLayer(childLayer, rootLayer, tempRes ult, hitTestRect, hitTestLocation, transformState, zOffsetForDescendants); 2105 hitLayer = hitTestPaginatedChildLayer(childLayer, rootLayer, tempRes ult, hitTestRect, hitTestLocation, transformState, zOffsetForDescendants);
2100 else 2106 else
2101 hitLayer = childLayer->hitTestLayer(rootLayer, this, tempResult, hit TestRect, hitTestLocation, false, transformState, zOffsetForDescendants); 2107 hitLayer = childLayer->hitTestLayer(rootLayer, this, tempResult, hit TestRect, hitTestLocation, false, transformState, zOffsetForDescendants);
2102 2108
2103 // If it is a list-based test, we can safely append the temporary result since it might had hit 2109 // If it is a list-based test, we can safely append the temporary result since it might had hit
2104 // nodes but not necesserily had hitLayer set. 2110 // nodes but not necesserily had hitLayer set.
2105 ASSERT(!result.isRectBasedTest() || result.hitTestRequest().listBased()) ; 2111 ASSERT(!result.isRectBasedTest() || result.hitTestRequest().listBased()) ;
2106 if (result.hitTestRequest().listBased()) 2112 if (result.hitTestRequest().listBased())
2107 result.append(tempResult); 2113 result.append(tempResult);
2108 2114
2109 if (isHitCandidate(hitLayer, depthSortDescendants, zOffset, unflattenedT ransformState)) { 2115 if (isHitCandidate(hitLayer, depthSortDescendants, zOffset, unflattenedT ransformState)) {
2110 resultLayer = hitLayer; 2116 resultLayer = hitLayer;
2111 if (!result.hitTestRequest().listBased()) 2117 if (!result.hitTestRequest().listBased())
2112 result = tempResult; 2118 result = tempResult;
2113 if (!depthSortDescendants) 2119 if (!depthSortDescendants)
2114 break; 2120 break;
2121 } else if (!hitLayer) {
2122 result.setValidityRect(tempResult.validityRect());
2115 } 2123 }
2116 } 2124 }
2117 2125
2118 return resultLayer; 2126 return resultLayer;
2119 } 2127 }
2120 2128
2121 DeprecatedPaintLayer* DeprecatedPaintLayer::hitTestPaginatedChildLayer(Deprecate dPaintLayer* childLayer, DeprecatedPaintLayer* rootLayer, HitTestResult& result, 2129 DeprecatedPaintLayer* DeprecatedPaintLayer::hitTestPaginatedChildLayer(Deprecate dPaintLayer* childLayer, DeprecatedPaintLayer* rootLayer, HitTestResult& result,
2122 const LayoutRect& hitTestRect, const HitTestLocation& hitTestLocation, const HitTestingTransformState* transformState, double* zOffset) 2130 const LayoutRect& hitTestRect, const HitTestLocation& hitTestLocation, const HitTestingTransformState* transformState, double* zOffset)
2123 { 2131 {
2124 Vector<DeprecatedPaintLayer*> columnLayers; 2132 Vector<DeprecatedPaintLayer*> columnLayers;
(...skipping 854 matching lines...) Expand 10 before | Expand all | Expand 10 after
2979 2987
2980 void showLayerTree(const blink::LayoutObject* layoutObject) 2988 void showLayerTree(const blink::LayoutObject* layoutObject)
2981 { 2989 {
2982 if (!layoutObject) { 2990 if (!layoutObject) {
2983 fprintf(stderr, "Cannot showLayerTree. Root is (nil)\n"); 2991 fprintf(stderr, "Cannot showLayerTree. Root is (nil)\n");
2984 return; 2992 return;
2985 } 2993 }
2986 showLayerTree(layoutObject->enclosingLayer()); 2994 showLayerTree(layoutObject->enclosingLayer());
2987 } 2995 }
2988 #endif 2996 #endif
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698