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

Unified Diff: Source/core/rendering/RenderObject.cpp

Issue 17471008: Rework compositor touch hit testing (Closed) Base URL: https://chromium.googlesource.com/chromium/blink.git@master
Patch Set: Various fixes and test additions Created 7 years, 5 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 side-by-side diff with in-line comments
Download patch
Index: Source/core/rendering/RenderObject.cpp
diff --git a/Source/core/rendering/RenderObject.cpp b/Source/core/rendering/RenderObject.cpp
index a08b09ea579df1363cce8c85ad388e62bab2db78..05056d340300993bb5801f676ed48140178f79e7 100644
--- a/Source/core/rendering/RenderObject.cpp
+++ b/Source/core/rendering/RenderObject.cpp
@@ -34,6 +34,7 @@
#include "core/editing/FrameSelection.h"
#include "core/editing/htmlediting.h"
#include "core/html/HTMLElement.h"
+#include "core/html/HTMLFrameOwnerElement.h"
#include "core/page/EventHandler.h"
#include "core/page/Frame.h"
#include "core/page/FrameView.h"
@@ -639,6 +640,53 @@ RenderNamedFlowThread* RenderObject::renderNamedFlowThreadWrapper() const
return object && object->isRenderNamedFlowThread() ? toRenderNamedFlowThread(object) : 0;
}
+void RenderObject::enclosingCompositedLayerAndOffset(const RenderLayer** enclosingCompositedLayer, LayoutPoint& offset) const
+{
+ // Determine the new compositing layer and the offset from it.
+ RenderLayer* layer = enclosingLayer();
+ *enclosingCompositedLayer = layer->enclosingCompositingLayerForRepaint();
+
+ if (!*enclosingCompositedLayer) {
+ if (document()) {
+ if (HTMLFrameOwnerElement* ownerElement = document()->ownerElement()) {
+ if (RenderObject* parentDocRenderer = ownerElement->renderer()) {
+ // Nearest composited layer is in another document.
+ // TODO There must be a simpler way to achieve this!
+ // Would it be simpler to use FrameView::contentsToWindow/windowToContents as in
+ // convertTargetSpaceQuadToCompositedLayer in LinkHighlight.cpp?
+
+ // First get the offset of this frame within the composited layer.
+ parentDocRenderer->enclosingCompositedLayerAndOffset(enclosingCompositedLayer, offset);
+
+ // Add the offset of the frame contents within the frame (i.e. border+padding).
+ if (parentDocRenderer->isBox())
+ offset.moveBy(toRenderBox(parentDocRenderer)->contentBoxRect().location());
+
+ // Now add the offset of this object within our frame.
+ TransformState transformState(TransformState::ApplyTransformDirection, FloatPoint());
+ mapLocalToContainer(view(), transformState, ApplyContainerFlip | UseTransforms);
+ transformState.flatten();
+ offset.moveBy(LayoutPoint(transformState.lastPlanarPoint()));
+
+ // And subtract the scroll offset of this frame.
+ offset -= frame()->view()->scrollOffset();
+ }
+ }
+ }
+ return;
+ }
+
+ // Self-painting layers subtract the renderer's location. Otherwise, we need to map our location to layer space.
+ if ((*enclosingCompositedLayer)->renderer() == this) {
+ offset = LayoutPoint();
+ } else {
+ TransformState transformState(TransformState::ApplyTransformDirection, FloatPoint());
+ mapLocalToContainer((*enclosingCompositedLayer)->renderer(), transformState, ApplyContainerFlip | UseTransforms);
+ transformState.flatten();
+ offset = LayoutPoint(transformState.lastPlanarPoint());
+ }
+}
+
RenderBlock* RenderObject::firstLineBlock() const
{
return 0;
@@ -2267,6 +2315,49 @@ LayoutRect RenderObject::localCaretRect(InlineBox*, int, LayoutUnit* extraWidthT
return LayoutRect();
}
+void RenderObject::computeLayerHitTestRects(LayerHitTestRects& layerRects) const
+{
+ // Figure out what composited layer our container is in. Any offset (or new layer) for this
+ // renderer within it's container will be applied in addLayerHitTestRects.
+ LayoutPoint layerOffset;
+ const RenderLayer* currentCompositedLayer;
+ if (container())
+ container()->enclosingCompositedLayerAndOffset(&currentCompositedLayer, layerOffset);
+ else
+ enclosingCompositedLayerAndOffset(&currentCompositedLayer, layerOffset);
+ if (!currentCompositedLayer)
+ return;
+
+ this->addLayerHitTestRects(layerRects, currentCompositedLayer, layerOffset);
+}
+
+void RenderObject::addLayerHitTestRects(LayerHitTestRects& layerRects, const RenderLayer* currentCompositedLayer, const LayoutPoint& layerOffset) const
+{
+ ASSERT(currentCompositedLayer);
+
+ // If it's possible for children to have rects outside our bounds, then we need to descend into the
+ // children and compute them.
+ // TODO: Any tighter guarantee on when we don't need to descend into children?
leviw_travelin_and_unemployed 2013/07/10 01:51:16 I don't think there's any tighter guarantee, but g
+ // TODO: Should I improve Region and use it? https://bugs.webkit.org/show_bug.cgi?id=100814
+ if (!isRoot()) {
+ for (RenderObject* curr = firstChild(); curr; curr = curr->nextSibling()) {
+ // TODO: levi's original patch excluded curr->isText(), curr->isListMarker() and !curr->isBox(). Why?
leviw_travelin_and_unemployed 2013/07/10 01:51:16 I can't recall on the latter two, but text nodes a
+ curr->addLayerHitTestRects(layerRects, currentCompositedLayer, layerOffset);
+ }
+ }
+
+ // Compute the rects for this renderer only and add them to the results.
+ // TODO: We could avoid passing the offset here and instead offset each result.
+ Vector<IntRect> ownRects;
+ computeOwnHitTestRects(ownRects, layerOffset);
+
+ LayerHitTestRects::iterator iter = layerRects.find(currentCompositedLayer);
+ if (iter == layerRects.end())
+ layerRects.add(currentCompositedLayer, ownRects);
+ else
+ iter->value.append(ownRects);
+}
+
bool RenderObject::isRooted(RenderView** view) const
{
const RenderObject* o = this;

Powered by Google App Engine
This is Rietveld 408576698