Closed
Bug 1365088
Opened 7 years ago
Closed 7 years ago
APZ hit testing unnecessarily calls HitTestingTreeNode::Untransform() twice on each node
Categories
(Core :: Panning and Zooming, enhancement, P3)
Core
Panning and Zooming
Tracking
()
RESOLVED
FIXED
mozilla55
Tracking | Status | |
---|---|---|
firefox55 | --- | fixed |
People
(Reporter: botond, Assigned: botond)
References
Details
(Whiteboard: [gfx-noted])
Attachments
(1 file)
The first call is in the pre-action of the ForEachNode call in APZCTreeManager::GetAPZCAtPoint(). The second call is inside the HitTest() call in the post-action of the same ForEachNode call. The two calls operate on the same point, so they're redundant.
Comment hidden (mozreview-request) |
Assignee | ||
Comment 2•7 years ago
|
||
I had to remove the MOZ_ASSERT(!IsOutsideClip(aPoint)) from HitTestingTreeNode::HitTest(), since it now takes the point already in Layer space. I think that should be fine. HitTest() only has one call site, and it's clear from the structure of that code that we only call it if ItOutsideClip() was false.
Assignee | ||
Comment 3•7 years ago
|
||
https://treeherder.mozilla.org/#/jobs?repo=try&revision=e9ca613d673b2765651f23efc1b0c7dfcfe41fbf
Comment 4•7 years ago
|
||
mozreview-review |
Comment on attachment 8867921 [details] Bug 1365088 - Avoid calling HitTestingTreeNode::Untransform() twice for each node during hit testing. https://reviewboard.mozilla.org/r/139452/#review143038 r+ assuming the pop/top ordering change was an error and can be undone. ::: gfx/layers/apz/src/APZCTreeManager.cpp:1868 (Diff revision 1) > HitTestResult hitResult = aNode->HitTest(hitTestPoints.top()); > + hitTestPoints.pop(); I don't understand why you swapped the order here. Shouldn't the pop() call still go before we read the top() value? The rest of the code seems to introduce no functional changes, so I wouldn't expect that a functional change is needed here.
Attachment #8867921 -
Flags: review?(bugmail) → review+
Updated•7 years ago
|
Priority: -- → P3
Whiteboard: [gfx-noted]
Comment hidden (mozreview-request) |
Assignee | ||
Comment 6•7 years ago
|
||
The pop/top ordering change is deliberate, and important for correctness. Consider a layer tree with a parent layer P and a child layer C. Suppose C has bounds (0,0,50,50), and a scale transform of 2x, so that it takes up (0,0,100,100) in screen space. Suppose P has bounds (0,0,200,200). In this scenario, hit-testing the screen point (75, 75) should hit C. Here's what happens during that hit testing before this change: start: push (75, 75) onto the stack pre-action for P: transform (75, 75) into (75, 75), push (75, 75) onto the stack pre-action for C: transform (75, 75) into (37.5, 37.5), push (37.5, 37.5) onto the stack post-action for C: { pop (37.5, 37.5) from the stack grab (75, 75) from the top of the stack pass (75, 75) into HitTest which transforms it into (37.5, 37.5) again which PASSES the hit test, so we hit C } Here's what happens with my change: start: push (75, 75) onto the stack pre-action for P: transform (75, 75) into (75, 75), push (75, 75) onto the stack pre-action for C: transform (75, 75) into (37.5, 37.5), push (37.5, 37.5) onto the stack post-action for C: { grab (37.5, 37.5) from the top of the stack pass (37.5, 37.5) into HitTest which no longer transforms it which PASSES the hit test, so we hit C pop (37.5, 37.5) from the stack } Here's what would happen if we didn't switch the order of the pop and top calls: start: push (75, 75) onto the stack pre-action for P: transform (75, 75) into (75, 75), push (75, 75) onto the stack pre-action for C: transform (75, 75) into (37.5, 37.5), push (37.5, 37.5) onto the stack post-action for C: { pop (37.5, 37.5) from the stack grab (75, 75) from the top of the stack pass (75, 75) into HitTest which no longer transforms it which FAILS the hit test, so we end up hitting P instead } I added a gtest exercising this scenario. The gtest passes with the code before the change, and with my change, but fails if we don't switch the order of the pop and top calls. (To exercise the scenario, I also had a fix a bug in the gtest fixture where we were incorrectly casting a LayerRect into ParentLayer space without using the transform to convert).
Assignee | ||
Comment 7•7 years ago
|
||
https://treeherder.mozilla.org/#/jobs?repo=try&revision=508a05db283f7742876239978984c98cecdd8b3a
Assignee | ||
Comment 8•7 years ago
|
||
Here's a conceptual explanation of the change: Previously, the pre-action would push a point onto the stack for use by the node's children's post-actions. Since nodes wanted a ParentLayer point in their post-action (to pass into HitTest), the Layer point pushed by a node was suitable for consumption by its children. Now, the pre-action pushes a point onto the stack for use by the node's own post-action. Since nodes now want a Layer point in their post-action (to pass into HitTest), the Layer point pushed by a node is suitable for consumption by its own post-action. Since the post-action now wants to consume the point its own pre-action pushed, rather than the point its parent's pre-action pushed, it looks at the top of the stack before popping.
Comment 9•7 years ago
|
||
Ah, that makes sense. Thanks for the explanation!
Comment 10•7 years ago
|
||
Pushed by bballo@mozilla.com: https://hg.mozilla.org/integration/autoland/rev/3f659e813e75 Avoid calling HitTestingTreeNode::Untransform() twice for each node during hit testing. r=kats
Comment 11•7 years ago
|
||
bugherder |
https://hg.mozilla.org/mozilla-central/rev/3f659e813e75
Status: NEW → RESOLVED
Closed: 7 years ago
status-firefox55:
--- → fixed
Resolution: --- → FIXED
Target Milestone: --- → mozilla55
You need to log in
before you can comment on or make changes to this bug.
Description
•