Commit 56501686 authored by Ria Jiang's avatar Ria Jiang Committed by Commit Bot

Use HitTestQuery to transform locations in RWHInputEventRouter.

Currently in RenderWidgetHostInputEventRouter, we use
TransformPointToCoordSpaceForView [1] to transform locations, which uses
SurfaceHittest in normal chrome. We don't want to use SurfaceHittest in
normal chrome and can't use SurfaceHittest in OOP-D.

This CL changes to use HitTestQuery::TransformLocationForTarget instead.

[1] https://cs.chromium.org/chromium/src/content/browser/renderer_host/render_widget_host_view_base.h?l=328

Bug: 811928
Test: site-per-process-hit-test-browsertests
Cq-Include-Trybots: master.tryserver.chromium.android:android_optional_gpu_tests_rel
Change-Id: Ie2ea51f0c12e17612aca17e322b592cdbdce5614
Reviewed-on: https://chromium-review.googlesource.com/917205
Commit-Queue: Ria Jiang <riajiang@chromium.org>
Reviewed-by: default avatarSadrul Chowdhury <sadrul@chromium.org>
Reviewed-by: default avatarKen Buchanan <kenrb@chromium.org>
Cr-Commit-Position: refs/heads/master@{#540387}
parent 30048681
...@@ -65,27 +65,28 @@ Target HitTestQuery::FindTargetForLocation( ...@@ -65,27 +65,28 @@ Target HitTestQuery::FindTargetForLocation(
return target; return target;
} }
gfx::PointF HitTestQuery::TransformLocationForTarget( bool HitTestQuery::TransformLocationForTarget(
EventSource event_source, EventSource event_source,
const std::vector<FrameSinkId>& target_ancestors, const std::vector<FrameSinkId>& target_ancestors,
const gfx::PointF& location_in_root) const { const gfx::PointF& location_in_root,
gfx::PointF* transformed_location) const {
SCOPED_UMA_HISTOGRAM_TIMER("Event.VizHitTest.TransformTime"); SCOPED_UMA_HISTOGRAM_TIMER("Event.VizHitTest.TransformTime");
if (!active_hit_test_list_size_) if (!active_hit_test_list_size_)
return location_in_root; return false;
if (target_ancestors.size() == 0u ||
target_ancestors[target_ancestors.size() - 1] !=
active_hit_test_list_->frame_sink_id) {
return false;
}
gfx::PointF location_in_target(location_in_root);
// TODO(riajiang): Cache the matrix product such that the transform can be // TODO(riajiang): Cache the matrix product such that the transform can be
// done immediately. crbug/758062. // done immediately. crbug/758062.
DCHECK(target_ancestors.size() > 0u && *transformed_location = location_in_root;
target_ancestors[target_ancestors.size() - 1] == return TransformLocationForTargetRecursively(
active_hit_test_list_->frame_sink_id);
bool success = TransformLocationForTargetRecursively(
event_source, target_ancestors, target_ancestors.size() - 1, event_source, target_ancestors, target_ancestors.size() - 1,
active_hit_test_list_, &location_in_target); active_hit_test_list_, transformed_location);
// Must provide a valid target.
DCHECK(success);
return location_in_target;
} }
bool HitTestQuery::FindTargetInRegionForLocation( bool HitTestQuery::FindTargetInRegionForLocation(
......
...@@ -80,14 +80,17 @@ class VIZ_HOST_EXPORT HitTestQuery { ...@@ -80,14 +80,17 @@ class VIZ_HOST_EXPORT HitTestQuery {
const gfx::PointF& location_in_root) const; const gfx::PointF& location_in_root) const;
// When a target window is already known, e.g. capture/latched window, convert // When a target window is already known, e.g. capture/latched window, convert
// |location_in_root| to be in the coordinate space of the target. // |location_in_root| to be in the coordinate space of the target and store
// that in |transformed_location|. Return true if the transform is successful
// and false otherwise.
// |target_ancestors| contains the FrameSinkId from target to root. // |target_ancestors| contains the FrameSinkId from target to root.
// |target_ancestors.front()| is the target, and |target_ancestors.back()| // |target_ancestors.front()| is the target, and |target_ancestors.back()|
// is the root. // is the root.
gfx::PointF TransformLocationForTarget( bool TransformLocationForTarget(
EventSource event_source, EventSource event_source,
const std::vector<FrameSinkId>& target_ancestors, const std::vector<FrameSinkId>& target_ancestors,
const gfx::PointF& location_in_root) const; const gfx::PointF& location_in_root,
gfx::PointF* transformed_location) const;
private: private:
// Helper function to find |target| for |location_in_parent| in the |region|, // Helper function to find |target| for |location_in_parent| in the |region|,
......
...@@ -378,21 +378,22 @@ TEST_F(HitTestQueryTest, ClippedChildWithChildUnderneathTransform) { ...@@ -378,21 +378,22 @@ TEST_F(HitTestQueryTest, ClippedChildWithChildUnderneathTransform) {
gfx::PointF point4(202, 202); gfx::PointF point4(202, 202);
std::vector<FrameSinkId> target_ancestors1{e_id}; std::vector<FrameSinkId> target_ancestors1{e_id};
EXPECT_EQ(hit_test_query().TransformLocationForTarget( gfx::PointF transformed_point;
EventSource::MOUSE, target_ancestors1, point1), EXPECT_TRUE(hit_test_query().TransformLocationForTarget(
point1); EventSource::MOUSE, target_ancestors1, point1, &transformed_point));
EXPECT_EQ(transformed_point, point1);
std::vector<FrameSinkId> target_ancestors2{a_id, c_id, e_id}; std::vector<FrameSinkId> target_ancestors2{a_id, c_id, e_id};
EXPECT_EQ(hit_test_query().TransformLocationForTarget( EXPECT_TRUE(hit_test_query().TransformLocationForTarget(
EventSource::MOUSE, target_ancestors2, point2), EventSource::MOUSE, target_ancestors2, point2, &transformed_point));
gfx::PointF(2, 2)); EXPECT_EQ(transformed_point, gfx::PointF(2, 2));
std::vector<FrameSinkId> target_ancestors3{d_id, e_id}; std::vector<FrameSinkId> target_ancestors3{d_id, e_id};
EXPECT_EQ(hit_test_query().TransformLocationForTarget( EXPECT_TRUE(hit_test_query().TransformLocationForTarget(
EventSource::MOUSE, target_ancestors3, point3), EventSource::MOUSE, target_ancestors3, point3, &transformed_point));
gfx::PointF(50, 100)); EXPECT_EQ(transformed_point, gfx::PointF(50, 100));
std::vector<FrameSinkId> target_ancestors4{b_id, c_id, e_id}; std::vector<FrameSinkId> target_ancestors4{b_id, c_id, e_id};
EXPECT_EQ(hit_test_query().TransformLocationForTarget( EXPECT_TRUE(hit_test_query().TransformLocationForTarget(
EventSource::MOUSE, target_ancestors4, point4), EventSource::MOUSE, target_ancestors4, point4, &transformed_point));
gfx::PointF(2, 2)); EXPECT_EQ(transformed_point, gfx::PointF(2, 2));
} }
// One embedder with two clipped children with a tab and transparent background. // One embedder with two clipped children with a tab and transparent background.
...@@ -571,31 +572,32 @@ TEST_F(HitTestQueryTest, ...@@ -571,31 +572,32 @@ TEST_F(HitTestQueryTest,
gfx::PointF point7(350, 1100); gfx::PointF point7(350, 1100);
std::vector<FrameSinkId> target_ancestors1{e_id}; std::vector<FrameSinkId> target_ancestors1{e_id};
EXPECT_EQ(hit_test_query().TransformLocationForTarget( gfx::PointF transformed_point;
EventSource::MOUSE, target_ancestors1, point1), EXPECT_TRUE(hit_test_query().TransformLocationForTarget(
point1); EventSource::MOUSE, target_ancestors1, point1, &transformed_point));
EXPECT_EQ(transformed_point, point1);
std::vector<FrameSinkId> target_ancestors2{a_id, c1_id, e_id}; std::vector<FrameSinkId> target_ancestors2{a_id, c1_id, e_id};
EXPECT_EQ(hit_test_query().TransformLocationForTarget( EXPECT_TRUE(hit_test_query().TransformLocationForTarget(
EventSource::MOUSE, target_ancestors2, point2), EventSource::MOUSE, target_ancestors2, point2, &transformed_point));
gfx::PointF(2, 2)); EXPECT_EQ(transformed_point, gfx::PointF(2, 2));
EXPECT_EQ(hit_test_query().TransformLocationForTarget( EXPECT_TRUE(hit_test_query().TransformLocationForTarget(
EventSource::MOUSE, target_ancestors1, point3), EventSource::MOUSE, target_ancestors1, point3, &transformed_point));
point3); EXPECT_EQ(transformed_point, point3);
std::vector<FrameSinkId> target_ancestors3{b_id, c1_id, e_id}; std::vector<FrameSinkId> target_ancestors3{b_id, c1_id, e_id};
EXPECT_EQ(hit_test_query().TransformLocationForTarget( EXPECT_TRUE(hit_test_query().TransformLocationForTarget(
EventSource::MOUSE, target_ancestors3, point4), EventSource::MOUSE, target_ancestors3, point4, &transformed_point));
gfx::PointF(2, 2)); EXPECT_EQ(transformed_point, gfx::PointF(2, 2));
std::vector<FrameSinkId> target_ancestors4{g_id, c2_id, e_id}; std::vector<FrameSinkId> target_ancestors4{g_id, c2_id, e_id};
EXPECT_EQ(hit_test_query().TransformLocationForTarget( EXPECT_TRUE(hit_test_query().TransformLocationForTarget(
EventSource::MOUSE, target_ancestors4, point5), EventSource::MOUSE, target_ancestors4, point5, &transformed_point));
gfx::PointF(50, 50)); EXPECT_EQ(transformed_point, gfx::PointF(50, 50));
EXPECT_EQ(hit_test_query().TransformLocationForTarget( EXPECT_TRUE(hit_test_query().TransformLocationForTarget(
EventSource::MOUSE, target_ancestors1, point6), EventSource::MOUSE, target_ancestors1, point6, &transformed_point));
point6); EXPECT_EQ(transformed_point, point6);
std::vector<FrameSinkId> target_ancestors5{h_id, c2_id, e_id}; std::vector<FrameSinkId> target_ancestors5{h_id, c2_id, e_id};
EXPECT_EQ(hit_test_query().TransformLocationForTarget( EXPECT_TRUE(hit_test_query().TransformLocationForTarget(
EventSource::MOUSE, target_ancestors5, point7), EventSource::MOUSE, target_ancestors5, point7, &transformed_point));
gfx::PointF(150, 300)); EXPECT_EQ(transformed_point, gfx::PointF(150, 300));
} }
// Children that are multiple layers deep. // Children that are multiple layers deep.
......
...@@ -42,6 +42,26 @@ blink::WebGestureEvent DummyGestureScrollUpdate(double timeStampSeconds) { ...@@ -42,6 +42,26 @@ blink::WebGestureEvent DummyGestureScrollUpdate(double timeStampSeconds) {
timeStampSeconds); timeStampSeconds);
} }
viz::HitTestQuery* GetHitTestQuery(
viz::HostFrameSinkManager* host_frame_sink_manager,
const viz::FrameSinkId& frame_sink_id) {
DCHECK(frame_sink_id.is_valid());
const auto& display_hit_test_query_map =
host_frame_sink_manager->display_hit_test_query();
const auto iter = display_hit_test_query_map.find(frame_sink_id);
if (iter == display_hit_test_query_map.end())
return nullptr;
return iter->second.get();
}
gfx::PointF ComputePointInRootInPixels(
const gfx::PointF& point,
content::RenderWidgetHostViewBase* root_view,
float device_scale_factor) {
gfx::PointF point_in_root = point + root_view->GetOffsetFromRootSurface();
return gfx::ConvertPointToPixel(device_scale_factor, point_in_root);
}
} // anonymous namespace } // anonymous namespace
namespace content { namespace content {
...@@ -211,8 +231,9 @@ RenderWidgetTargetResult RenderWidgetHostInputEventRouter::FindMouseEventTarget( ...@@ -211,8 +231,9 @@ RenderWidgetTargetResult RenderWidgetHostInputEventRouter::FindMouseEventTarget(
} }
if (needs_transform_point) { if (needs_transform_point) {
if (!root_view->TransformPointToCoordSpaceForView( if (!TransformPointToTargetCoordSpace(
event.PositionInWidget(), target, &transformed_point)) { root_view, target, event.PositionInWidget(), &transformed_point,
viz::EventSource::MOUSE)) {
return {nullptr, false, base::nullopt}; return {nullptr, false, base::nullopt};
} }
} }
...@@ -230,8 +251,9 @@ RenderWidgetHostInputEventRouter::FindMouseWheelEventTarget( ...@@ -230,8 +251,9 @@ RenderWidgetHostInputEventRouter::FindMouseWheelEventTarget(
->delegate() ->delegate()
->GetMouseLockWidget() ->GetMouseLockWidget()
->GetView(); ->GetView();
if (!root_view->TransformPointToCoordSpaceForView( if (!TransformPointToTargetCoordSpace(
event.PositionInWidget(), target, &transformed_point)) { root_view, target, event.PositionInWidget(), &transformed_point,
viz::EventSource::MOUSE)) {
return {nullptr, false, base::nullopt}; return {nullptr, false, base::nullopt};
} }
return {target, false, transformed_point}; return {target, false, transformed_point};
...@@ -271,22 +293,18 @@ RenderWidgetTargetResult RenderWidgetHostInputEventRouter::FindViewAtLocation( ...@@ -271,22 +293,18 @@ RenderWidgetTargetResult RenderWidgetHostInputEventRouter::FindViewAtLocation(
viz::FrameSinkId frame_sink_id; viz::FrameSinkId frame_sink_id;
bool query_renderer = false; bool query_renderer = false;
if (use_viz_hit_test_) { if (use_viz_hit_test_) {
const auto& display_hit_test_query_map = viz::HitTestQuery* query = GetHitTestQuery(GetHostFrameSinkManager(),
GetHostFrameSinkManager()->display_hit_test_query(); root_view->GetRootFrameSinkId());
const auto iter = if (!query)
display_hit_test_query_map.find(root_view->GetRootFrameSinkId());
if (iter == display_hit_test_query_map.end())
return {root_view, false, base::nullopt}; return {root_view, false, base::nullopt};
// |point_in_screen| is in the coordinate space of of the screen, but the // |point_in_screen| is in the coordinate space of of the screen, but the
// display HitTestQuery does a hit test in the coordinate space of the root // display HitTestQuery does a hit test in the coordinate space of the root
// window. The following translation should account for that discrepancy. // window. The following translation should account for that discrepancy.
// TODO(riajiang): Get rid of |point_in_screen| since it's not used. // TODO(riajiang): Get rid of |point_in_screen| since it's not used.
gfx::PointF point_in_root = point + root_view->GetOffsetFromRootSurface();
viz::HitTestQuery* query = iter->second.get();
float device_scale_factor = root_view->GetDeviceScaleFactor(); float device_scale_factor = root_view->GetDeviceScaleFactor();
DCHECK(device_scale_factor != 0.0f); DCHECK_GT(device_scale_factor, 0.0f);
gfx::PointF point_in_root_in_pixels = gfx::PointF point_in_root_in_pixels =
gfx::ConvertPointToPixel(device_scale_factor, point_in_root); ComputePointInRootInPixels(point, root_view, device_scale_factor);
viz::Target target = viz::Target target =
query->FindTargetForLocation(source, point_in_root_in_pixels); query->FindTargetForLocation(source, point_in_root_in_pixels);
frame_sink_id = target.frame_sink_id; frame_sink_id = target.frame_sink_id;
...@@ -672,9 +690,11 @@ void RenderWidgetHostInputEventRouter::SendMouseEnterOrLeaveEvents( ...@@ -672,9 +690,11 @@ void RenderWidgetHostInputEventRouter::SendMouseEnterOrLeaveEvents(
// new compositor surface. The SurfaceID for that might not have // new compositor surface. The SurfaceID for that might not have
// propagated to its embedding surface, which makes it impossible to // propagated to its embedding surface, which makes it impossible to
// compute the transformation for it // compute the transformation for it
if (!root_view->TransformPointToCoordSpaceForView(event.PositionInWidget(), if (!TransformPointToTargetCoordSpace(
view, &transformed_point)) root_view, view, event.PositionInWidget(), &transformed_point,
viz::EventSource::MOUSE)) {
transformed_point = gfx::PointF(); transformed_point = gfx::PointF();
}
mouse_leave.SetPositionInWidget(transformed_point.x(), mouse_leave.SetPositionInWidget(transformed_point.x(),
transformed_point.y()); transformed_point.y());
view->ProcessMouseEvent(mouse_leave, ui::LatencyInfo()); view->ProcessMouseEvent(mouse_leave, ui::LatencyInfo());
...@@ -684,9 +704,11 @@ void RenderWidgetHostInputEventRouter::SendMouseEnterOrLeaveEvents( ...@@ -684,9 +704,11 @@ void RenderWidgetHostInputEventRouter::SendMouseEnterOrLeaveEvents(
if (common_ancestor && common_ancestor != target) { if (common_ancestor && common_ancestor != target) {
blink::WebMouseEvent mouse_move(event); blink::WebMouseEvent mouse_move(event);
mouse_move.SetType(blink::WebInputEvent::kMouseMove); mouse_move.SetType(blink::WebInputEvent::kMouseMove);
if (!root_view->TransformPointToCoordSpaceForView( if (!TransformPointToTargetCoordSpace(
event.PositionInWidget(), common_ancestor, &transformed_point)) root_view, common_ancestor, event.PositionInWidget(),
&transformed_point, viz::EventSource::MOUSE)) {
transformed_point = gfx::PointF(); transformed_point = gfx::PointF();
}
mouse_move.SetPositionInWidget(transformed_point.x(), mouse_move.SetPositionInWidget(transformed_point.x(),
transformed_point.y()); transformed_point.y());
common_ancestor->ProcessMouseEvent(mouse_move, ui::LatencyInfo()); common_ancestor->ProcessMouseEvent(mouse_move, ui::LatencyInfo());
...@@ -698,9 +720,11 @@ void RenderWidgetHostInputEventRouter::SendMouseEnterOrLeaveEvents( ...@@ -698,9 +720,11 @@ void RenderWidgetHostInputEventRouter::SendMouseEnterOrLeaveEvents(
continue; continue;
blink::WebMouseEvent mouse_enter(event); blink::WebMouseEvent mouse_enter(event);
mouse_enter.SetType(blink::WebInputEvent::kMouseMove); mouse_enter.SetType(blink::WebInputEvent::kMouseMove);
if (!root_view->TransformPointToCoordSpaceForView(event.PositionInWidget(), if (!TransformPointToTargetCoordSpace(
view, &transformed_point)) root_view, view, event.PositionInWidget(), &transformed_point,
viz::EventSource::MOUSE)) {
transformed_point = gfx::PointF(); transformed_point = gfx::PointF();
}
mouse_enter.SetPositionInWidget(transformed_point.x(), mouse_enter.SetPositionInWidget(transformed_point.x(),
transformed_point.y()); transformed_point.y());
view->ProcessMouseEvent(mouse_enter, ui::LatencyInfo()); view->ProcessMouseEvent(mouse_enter, ui::LatencyInfo());
...@@ -1187,6 +1211,53 @@ RenderWidgetHostInputEventRouter::GetRenderWidgetTargeterForTests() { ...@@ -1187,6 +1211,53 @@ RenderWidgetHostInputEventRouter::GetRenderWidgetTargeterForTests() {
return event_targeter_.get(); return event_targeter_.get();
} }
bool RenderWidgetHostInputEventRouter::TransformPointToTargetCoordSpace(
RenderWidgetHostViewBase* root_view,
RenderWidgetHostViewBase* target,
const gfx::PointF& point,
gfx::PointF* transformed_point,
viz::EventSource source) const {
if (root_view == target) {
*transformed_point = point;
return true;
}
if (!use_viz_hit_test_) {
return root_view->TransformPointToCoordSpaceForView(point, target,
transformed_point);
}
viz::HitTestQuery* query = GetHitTestQuery(GetHostFrameSinkManager(),
root_view->GetRootFrameSinkId());
if (!query)
return false;
std::vector<viz::FrameSinkId> target_ancestors;
target_ancestors.push_back(target->GetFrameSinkId());
RenderWidgetHostViewBase* cur_view = target;
while (cur_view->IsRenderWidgetHostViewChildFrame()) {
cur_view =
static_cast<RenderWidgetHostViewChildFrame*>(cur_view)->GetParentView();
DCHECK(cur_view);
target_ancestors.push_back(cur_view->GetFrameSinkId());
}
DCHECK_EQ(cur_view, root_view);
target_ancestors.push_back(root_view->GetRootFrameSinkId());
float device_scale_factor = root_view->GetDeviceScaleFactor();
DCHECK_GT(device_scale_factor, 0.0f);
gfx::PointF point_in_root_in_pixels =
ComputePointInRootInPixels(point, root_view, device_scale_factor);
if (!query->TransformLocationForTarget(source, target_ancestors,
point_in_root_in_pixels,
transformed_point)) {
return false;
}
*transformed_point =
gfx::ConvertPointToDIP(device_scale_factor, *transformed_point);
return true;
}
RenderWidgetTargetResult RenderWidgetTargetResult
RenderWidgetHostInputEventRouter::FindTargetSynchronously( RenderWidgetHostInputEventRouter::FindTargetSynchronously(
RenderWidgetHostViewBase* root_view, RenderWidgetHostViewBase* root_view,
......
...@@ -221,6 +221,15 @@ class CONTENT_EXPORT RenderWidgetHostInputEventRouter ...@@ -221,6 +221,15 @@ class CONTENT_EXPORT RenderWidgetHostInputEventRouter
const ui::LatencyInfo& latency, const ui::LatencyInfo& latency,
const base::Optional<gfx::PointF>& target_location); const base::Optional<gfx::PointF>& target_location);
// Transforms |point| from |root_view| coord space to |target| coord space.
// Result is stored in |transformed_point|. Returns true if the transform
// is successful, false otherwise.
bool TransformPointToTargetCoordSpace(RenderWidgetHostViewBase* root_view,
RenderWidgetHostViewBase* target,
const gfx::PointF& point,
gfx::PointF* transformed_point,
viz::EventSource source) const;
// RenderWidgetTargeter::Delegate: // RenderWidgetTargeter::Delegate:
RenderWidgetTargetResult FindTargetSynchronously( RenderWidgetTargetResult FindTargetSynchronously(
RenderWidgetHostViewBase* root_view, RenderWidgetHostViewBase* root_view,
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment