0

Creates RenderInputRouterSupport with CompositorFrameSink's creation for input

handling on Viz.

This CL does the following:
* Hooks up creation of appropriate RenderInputRouterSupport* class to mirror
RenderWidgetHostViewInput interface implementation in Viz for a FrameSinkId.
This information is stored in FrameSinkMetadata structure.
* Adds traversal methods, namely Get(Parent|Root)RenderInputRouterSupport to
InputManager, allowing getting parent/root RenderInputRouterSupportBase* class
from a child frame. Added tests for the traversals.
* Refactors RenderWidgetHostViewInput interface and implements some additional
methods for the same interface in RenderInputRouterSupportBase.

Doc Link:
https://docs.google.com/document/d/1tRPUd11fuPcXxb2ep_kGYPahgv0OOlV7DvsGkbom7VA/

Bug: b:367695776, b:373888054
Change-Id: Ia61f1848abc0598f7f385a6b4d1202109ca3fa71
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/5941108
Reviewed-by: Jonathan Ross <jonross@chromium.org>
Commit-Queue: Aman Verma <amanvr@google.com>
Cr-Commit-Position: refs/heads/main@{#1372706}
This commit is contained in:
Aman Verma
2024-10-23 15:15:59 +00:00
committed by Chromium LUCI CQ
parent 2fc5d0b6bd
commit b117363c8e
13 changed files with 247 additions and 11 deletions

@ -43,6 +43,11 @@ bool RenderWidgetHostViewInput::ScreenRectIsUnstableForIOv2For(
return false;
}
gfx::PointF RenderWidgetHostViewInput::TransformPointToRootCoordSpaceF(
const gfx::PointF& point) {
return point;
}
gfx::PointF RenderWidgetHostViewInput::TransformRootPointToViewCoordSpace(
const gfx::PointF& point) {
return point;

@ -123,8 +123,7 @@ class COMPONENT_EXPORT(INPUT) RenderWidgetHostViewInput
// the top-level frame's renderer this is a no-op as they are already
// properly transformed; however, coordinates received from an out-of-process
// iframe renderer process require transformation.
virtual gfx::PointF TransformPointToRootCoordSpaceF(
const gfx::PointF& point) = 0;
virtual gfx::PointF TransformPointToRootCoordSpaceF(const gfx::PointF& point);
// Converts a point in the root view's coordinate space to the coordinate
// space of whichever view is used to call this method.

@ -1082,6 +1082,11 @@ void FrameSinkManagerImpl::OnScreenshotCaptured(
std::move(copy_output_result));
}
bool FrameSinkManagerImpl::IsFrameSinkIdInRootSinkMap(
const FrameSinkId& frame_sink_id) {
return root_sink_map_.find(frame_sink_id) != root_sink_map_.end();
}
gpu::SharedImageInterface* FrameSinkManagerImpl::GetSharedImageInterface() {
DCHECK(shared_image_interface_provider_);
return shared_image_interface_provider_->GetSharedImageInterface();

@ -358,6 +358,8 @@ class VIZ_SERVICE_EXPORT FrameSinkManagerImpl
destination_token,
std::unique_ptr<CopyOutputResult> copy_output_result);
bool IsFrameSinkIdInRootSinkMap(const FrameSinkId& frame_sink_id);
base::WeakPtr<FrameSinkManagerImpl> GetWeakPtr() {
return weak_factory_.GetWeakPtr();
}

@ -1384,6 +1384,119 @@ TEST_P(AndroidFrameSinkManagerTest, VizRIRDelegateLifecycle) {
}
}
TEST_P(AndroidFrameSinkManagerTest, RenderInputRouterSupportTraversals) {
const bool expected_creation = input::IsTransferInputToVizSupported();
if (!expected_creation) {
return;
}
RootCompositorFrameSinkData root_data1;
manager_.CreateRootCompositorFrameSink(
root_data1.BuildParams(kFrameSinkIdRoot));
EXPECT_TRUE(CompositorFrameSinkExists(kFrameSinkIdRoot));
RootCompositorFrameSinkData root_data2;
manager_.CreateRootCompositorFrameSink(
root_data2.BuildParams(kFrameSinkIdRoot2));
EXPECT_TRUE(CompositorFrameSinkExists(kFrameSinkIdRoot2));
manager_.RegisterFrameSinkId(kFrameSinkIdA, true /* report_activation */);
manager_.RegisterFrameSinkId(kFrameSinkIdB, true /* report_activation */);
manager_.RegisterFrameSinkId(kFrameSinkIdC, true /* report_activation */);
manager_.RegisterFrameSinkId(kFrameSinkIdD, true /* report_activation */);
manager_.RegisterFrameSinkId(kFrameSinkIdE, true /* report_activation */);
// Create CompositorFrameSinkImpl's.
CreateCompositorFrameSink(kFrameSinkIdA, CreateRIRConfig(/*grouping_id=*/1));
CreateCompositorFrameSink(kFrameSinkIdB, CreateRIRConfig(/*grouping_id=*/1));
CreateCompositorFrameSink(kFrameSinkIdC, CreateRIRConfig(/*grouping_id=*/1));
CreateCompositorFrameSink(kFrameSinkIdD, CreateRIRConfig(/*grouping_id=*/1));
CreateCompositorFrameSink(kFrameSinkIdE, CreateRIRConfig(/*grouping_id=*/1));
// Set up initial hierarchy.
// root1 -> A -> B -> C
// + -> D
// root2 -> E
manager_.RegisterFrameSinkHierarchy(kFrameSinkIdRoot, kFrameSinkIdA);
manager_.RegisterFrameSinkHierarchy(kFrameSinkIdRoot2, kFrameSinkIdE);
manager_.RegisterFrameSinkHierarchy(kFrameSinkIdA, kFrameSinkIdB);
EXPECT_EQ(
GetMockInputManager()->GetParentRenderInputRouterSupport(kFrameSinkIdB),
GetMockInputManager()->GetSupportForFrameSink(kFrameSinkIdA));
manager_.RegisterFrameSinkHierarchy(kFrameSinkIdB, kFrameSinkIdC);
EXPECT_EQ(
GetMockInputManager()->GetParentRenderInputRouterSupport(kFrameSinkIdC),
GetMockInputManager()->GetSupportForFrameSink(kFrameSinkIdB));
manager_.RegisterFrameSinkHierarchy(kFrameSinkIdB, kFrameSinkIdD);
EXPECT_EQ(
GetMockInputManager()->GetParentRenderInputRouterSupport(kFrameSinkIdD),
GetMockInputManager()->GetSupportForFrameSink(kFrameSinkIdB));
EXPECT_EQ(
GetMockInputManager()->GetRootRenderInputRouterSupport(kFrameSinkIdB),
GetMockInputManager()->GetSupportForFrameSink(kFrameSinkIdA));
EXPECT_EQ(
GetMockInputManager()->GetRootRenderInputRouterSupport(kFrameSinkIdC),
GetMockInputManager()->GetSupportForFrameSink(kFrameSinkIdA));
EXPECT_EQ(
GetMockInputManager()->GetRootRenderInputRouterSupport(kFrameSinkIdD),
GetMockInputManager()->GetSupportForFrameSink(kFrameSinkIdA));
// // Attach A into root2's subtree, like a window moving across displays.
// root1 -> A -> B -> C
// + -> D
// root2 -> E -> A -> B -> C
// + -> D
manager_.RegisterFrameSinkHierarchy(kFrameSinkIdE, kFrameSinkIdA);
// With the heuristic of just keeping existing parent in the face of multiple,
// no client's corresponding RootCompositorFrameSink should change.
EXPECT_EQ(
GetMockInputManager()->GetRootRenderInputRouterSupport(kFrameSinkIdB),
GetMockInputManager()->GetSupportForFrameSink(kFrameSinkIdA));
EXPECT_EQ(
GetMockInputManager()->GetRootRenderInputRouterSupport(kFrameSinkIdC),
GetMockInputManager()->GetSupportForFrameSink(kFrameSinkIdA));
EXPECT_EQ(
GetMockInputManager()->GetRootRenderInputRouterSupport(kFrameSinkIdD),
GetMockInputManager()->GetSupportForFrameSink(kFrameSinkIdA));
// Detach A from root1.
manager_.UnregisterFrameSinkHierarchy(kFrameSinkIdRoot, kFrameSinkIdA);
// root1
// root2 -> E -> A -> B -> C
// + -> D
EXPECT_EQ(
GetMockInputManager()->GetRootRenderInputRouterSupport(kFrameSinkIdB),
GetMockInputManager()->GetSupportForFrameSink(kFrameSinkIdE));
EXPECT_EQ(
GetMockInputManager()->GetRootRenderInputRouterSupport(kFrameSinkIdC),
GetMockInputManager()->GetSupportForFrameSink(kFrameSinkIdE));
EXPECT_EQ(
GetMockInputManager()->GetRootRenderInputRouterSupport(kFrameSinkIdD),
GetMockInputManager()->GetSupportForFrameSink(kFrameSinkIdE));
manager_.UnregisterFrameSinkHierarchy(kFrameSinkIdRoot2, kFrameSinkIdE);
manager_.UnregisterFrameSinkHierarchy(kFrameSinkIdA, kFrameSinkIdB);
manager_.UnregisterFrameSinkHierarchy(kFrameSinkIdB, kFrameSinkIdD);
manager_.UnregisterFrameSinkHierarchy(kFrameSinkIdB, kFrameSinkIdC);
manager_.UnregisterFrameSinkHierarchy(kFrameSinkIdE, kFrameSinkIdA);
// Delete RootCompositorFrameSinks.
manager_.InvalidateFrameSinkId(kFrameSinkIdRoot);
manager_.InvalidateFrameSinkId(kFrameSinkIdRoot2);
// Invalidating should destroy the CompositorFrameSinkImpl's.
manager_.InvalidateFrameSinkId(kFrameSinkIdA);
manager_.InvalidateFrameSinkId(kFrameSinkIdB);
manager_.InvalidateFrameSinkId(kFrameSinkIdC);
manager_.InvalidateFrameSinkId(kFrameSinkIdD);
manager_.InvalidateFrameSinkId(kFrameSinkIdE);
}
INSTANTIATE_TEST_SUITE_P(All,
AndroidFrameSinkManagerTest,
::testing::Bool(),

@ -13,6 +13,7 @@
#include "base/memory/scoped_refptr.h"
#include "base/metrics/histogram_macros.h"
#include "components/viz/service/input/render_input_router_delegate_impl.h"
#include "components/viz/service/input/render_input_router_support_child_frame.h"
#if BUILDFLAG(IS_ANDROID)
#include "base/android/android_input_receiver_compat.h"
@ -20,6 +21,7 @@
#include "components/input/android/scoped_input_receiver.h"
#include "components/input/android/scoped_input_receiver_callbacks.h"
#include "components/input/android/scoped_input_transfer_token.h"
#include "components/viz/service/input/render_input_router_support_android.h"
#include "gpu/ipc/common/gpu_surface_lookup.h"
#include "ui/gfx/android/android_surface_control_compat.h"
#include "ui/gl/android/scoped_a_native_window.h"
@ -29,8 +31,12 @@ namespace viz {
FrameSinkMetadata::FrameSinkMetadata(
uint32_t grouping_id,
std::unique_ptr<RenderInputRouterSupportBase> support,
std::unique_ptr<RenderInputRouterDelegateImpl> delegate)
: grouping_id(grouping_id), rir_delegate(std::move(delegate)) {}
: grouping_id(grouping_id),
rir_support(std::move(support)),
rir_delegate(std::move(delegate)) {}
FrameSinkMetadata::~FrameSinkMetadata() = default;
FrameSinkMetadata::FrameSinkMetadata(FrameSinkMetadata&& other) = default;
@ -124,7 +130,11 @@ void InputManager::OnCreateCompositorFrameSink(
base::SingleThreadTaskRunner::GetCurrentDefault());
frame_sink_metadata_map_.emplace(std::make_pair(
frame_sink_id, FrameSinkMetadata{grouping_id, std::move(rir_delegate)}));
frame_sink_id,
FrameSinkMetadata{grouping_id,
MakeRenderInputRouterSupport(render_input_router.get(),
frame_sink_id),
std::move(rir_delegate)}));
rir_map_.emplace(
std::make_pair(frame_sink_id, std::move(render_input_router)));
@ -164,6 +174,10 @@ input::TouchEmulator* InputManager::GetTouchEmulator(bool create_if_necessary) {
return nullptr;
}
const DisplayHitTestQueryMap& InputManager::GetDisplayHitTestQuery() const {
return frame_sink_manager_->GetDisplayHitTestQuery();
}
float InputManager::GetDeviceScaleFactorForId(
const FrameSinkId& frame_sink_id) {
auto* support = frame_sink_manager_->GetFrameSinkForId(frame_sink_id);
@ -178,6 +192,62 @@ FrameSinkId InputManager::GetRootCompositorFrameSinkId(
child_frame_sink_id);
}
RenderInputRouterSupportBase* InputManager::GetParentRenderInputRouterSupport(
const FrameSinkId& frame_sink_id) {
auto parent_id =
frame_sink_manager_->GetOldestParentByChildFrameId(frame_sink_id);
CHECK(!frame_sink_manager_->IsFrameSinkIdInRootSinkMap(parent_id));
auto it = frame_sink_metadata_map_.find(parent_id);
if (it != frame_sink_metadata_map_.end()) {
return it->second.rir_support.get();
}
DUMP_WILL_BE_NOTREACHED();
return nullptr;
}
RenderInputRouterSupportBase* InputManager::GetRootRenderInputRouterSupport(
const FrameSinkId& frame_sink_id) {
auto parent_frame_sink_id =
frame_sink_manager_->GetOldestParentByChildFrameId(frame_sink_id);
FrameSinkId current_id = frame_sink_id;
while (
!frame_sink_manager_->IsFrameSinkIdInRootSinkMap(parent_frame_sink_id)) {
current_id = parent_frame_sink_id;
parent_frame_sink_id = frame_sink_manager_->GetOldestParentByChildFrameId(
parent_frame_sink_id);
}
auto it = frame_sink_metadata_map_.find(current_id);
if (it != frame_sink_metadata_map_.end()) {
return it->second.rir_support.get();
}
DUMP_WILL_BE_NOTREACHED();
return nullptr;
}
std::unique_ptr<RenderInputRouterSupportBase>
InputManager::MakeRenderInputRouterSupport(input::RenderInputRouter* rir,
const FrameSinkId& frame_sink_id) {
TRACE_EVENT_INSTANT("input", "InputManager::MakeRenderInputRouterSupport");
auto parent_id =
frame_sink_manager_->GetOldestParentByChildFrameId(frame_sink_id);
if (frame_sink_manager_->IsFrameSinkIdInRootSinkMap(parent_id)) {
#if BUILDFLAG(IS_ANDROID)
return std::make_unique<RenderInputRouterSupportAndroid>(rir, this,
frame_sink_id);
#else
// InputVizard only supports Android currently.
NOTREACHED_NORETURN();
#endif
}
return std::make_unique<RenderInputRouterSupportChildFrame>(rir, this,
frame_sink_id);
}
#if BUILDFLAG(IS_ANDROID)
void InputManager::CreateAndroidInputReceiver(
const FrameSinkId& frame_sink_id,

@ -28,6 +28,7 @@ namespace viz {
struct FrameSinkMetadata {
explicit FrameSinkMetadata(
uint32_t grouping_id,
std::unique_ptr<RenderInputRouterSupportBase> support,
std::unique_ptr<RenderInputRouterDelegateImpl> delegate);
FrameSinkMetadata(const FrameSinkMetadata&) = delete;
@ -39,6 +40,7 @@ struct FrameSinkMetadata {
~FrameSinkMetadata();
uint32_t grouping_id;
std::unique_ptr<RenderInputRouterSupportBase> rir_support;
std::unique_ptr<RenderInputRouterDelegateImpl> rir_delegate;
};
@ -69,11 +71,20 @@ class VIZ_SERVICE_EXPORT InputManager
input::TouchEmulator* GetTouchEmulator(bool create_if_necessary) override;
// RenderInputRouterSupportBase::Delegate implementation.
const DisplayHitTestQueryMap& GetDisplayHitTestQuery() const override;
float GetDeviceScaleFactorForId(const FrameSinkId& frame_sink_id) override;
FrameSinkId GetRootCompositorFrameSinkId(
const FrameSinkId& child_frame_sink_id) override;
RenderInputRouterSupportBase* GetParentRenderInputRouterSupport(
const FrameSinkId& frame_sink_id) override;
RenderInputRouterSupportBase* GetRootRenderInputRouterSupport(
const FrameSinkId& frame_sink_id) override;
private:
std::unique_ptr<RenderInputRouterSupportBase> MakeRenderInputRouterSupport(
input::RenderInputRouter* rir,
const FrameSinkId& frame_sink_id);
#if BUILDFLAG(IS_ANDROID)
void CreateAndroidInputReceiver(const FrameSinkId& frame_sink_id,
const gpu::SurfaceHandle& surface_handle);

@ -16,4 +16,9 @@ bool MockInputManager::RIRExistsForFrameSinkId(
return base::Contains(rir_map_, frame_sink_id);
}
RenderInputRouterSupportBase* MockInputManager::GetSupportForFrameSink(
const FrameSinkId& id) {
return frame_sink_metadata_map_.find(id)->second.rir_support.get();
}
} // namespace viz

@ -6,6 +6,7 @@
#define COMPONENTS_VIZ_SERVICE_INPUT_MOCK_INPUT_MANAGER_H_
#include "components/viz/service/input/input_manager.h"
#include "components/viz/service/input/render_input_router_support_base.h"
namespace viz {
@ -13,6 +14,7 @@ class FrameSinkManagerImpl;
class MockInputManager : public InputManager {
public:
using InputManager::frame_sink_metadata_map_;
using InputManager::rir_map_;
explicit MockInputManager(FrameSinkManagerImpl* frame_sink_manager);
@ -26,6 +28,8 @@ class MockInputManager : public InputManager {
bool RIRExistsForFrameSinkId(const FrameSinkId& frame_sink_id);
int GetRenderInputRouterMapSize() { return rir_map_.size(); }
RenderInputRouterSupportBase* GetSupportForFrameSink(const FrameSinkId& id);
int GetInputEventRouterMapSize() { return rwhier_map_.size(); }
};

@ -88,16 +88,31 @@ RenderInputRouterSupportBase* RenderInputRouterSupportBase::GetRootView() {
return this;
}
const LocalSurfaceId& RenderInputRouterSupportBase::GetLocalSurfaceId() const {
// Not needed for input handling on Viz with InputVizard.
NOTREACHED();
}
const FrameSinkId& RenderInputRouterSupportBase::GetFrameSinkId() const {
return frame_sink_id_;
}
gfx::Size RenderInputRouterSupportBase::GetVisibleViewportSize() {
// TODO(374119530): Implement GetVisibleViewportSize in Viz.
NOTREACHED();
}
void RenderInputRouterSupportBase::OnAutoscrollStart() {
// Related to mouse events handling which on VizCompositor which is out of
// scope currently for InputVizard.
NOTREACHED();
}
const DisplayHitTestQueryMap&
RenderInputRouterSupportBase::GetDisplayHitTestQuery() const {
return delegate_->GetDisplayHitTestQuery();
}
float RenderInputRouterSupportBase::GetDeviceScaleFactor() const {
return delegate_->GetDeviceScaleFactorForId(GetFrameSinkId());
}

@ -23,10 +23,17 @@ class VIZ_SERVICE_EXPORT RenderInputRouterSupportBase
class Delegate {
public:
virtual const DisplayHitTestQueryMap& GetDisplayHitTestQuery() const = 0;
virtual float GetDeviceScaleFactorForId(
const FrameSinkId& frame_sink_id) = 0;
virtual FrameSinkId GetRootCompositorFrameSinkId(
const FrameSinkId& child_frame_sink_id) = 0;
// The following Get(Parent/Root)RenderInputRouterSupport methods should be
// called only from RenderInputRouterSupportChildFrame.
virtual RenderInputRouterSupportBase* GetParentRenderInputRouterSupport(
const FrameSinkId& frame_sink_id) = 0;
virtual RenderInputRouterSupportBase* GetRootRenderInputRouterSupport(
const FrameSinkId& frame_sink_id) = 0;
};
// StylusInterface implementation.
@ -45,8 +52,12 @@ class VIZ_SERVICE_EXPORT RenderInputRouterSupportBase
void ProcessGestureEvent(const blink::WebGestureEvent& event,
const ui::LatencyInfo& latency) override;
RenderInputRouterSupportBase* GetRootView() override;
const LocalSurfaceId& GetLocalSurfaceId() const override;
const FrameSinkId& GetFrameSinkId() const override;
gfx::Size GetVisibleViewportSize() override;
void OnAutoscrollStart() override;
void UpdateCursor(const ui::Cursor& cursor) override {}
const DisplayHitTestQueryMap& GetDisplayHitTestQuery() const override;
float GetDeviceScaleFactor() const final;
bool IsPointerLocked() override;

@ -31,9 +31,7 @@ const LocalSurfaceId& RenderInputRouterSupportChildFrame::GetLocalSurfaceId()
RenderInputRouterSupportBase*
RenderInputRouterSupportChildFrame::GetRootView() {
// TODO(373888054): Implement GetRootView and GetParentView for
// RenderInputRouterSupportChildFrame.
NOTREACHED();
return delegate()->GetRootRenderInputRouterSupport(GetFrameSinkId());
}
FrameSinkId RenderInputRouterSupportChildFrame::GetRootFrameSinkId() {
@ -97,9 +95,7 @@ void RenderInputRouterSupportChildFrame::TransformPointToRootSurface(
RenderInputRouterSupportBase*
RenderInputRouterSupportChildFrame::GetParentViewInput() {
// TODO(373888054): Implement GetRootView and GetParentView for
// RenderInputRouterSupportChildFrame.
NOTREACHED();
return delegate()->GetParentRenderInputRouterSupport(GetFrameSinkId());
}
RenderInputRouterSupportBase*

@ -702,7 +702,7 @@ void RenderWidgetHostViewBase::ProcessGestureEvent(
gfx::PointF RenderWidgetHostViewBase::TransformPointToRootCoordSpaceF(
const gfx::PointF& point) {
return point;
return RenderWidgetHostViewInput::TransformPointToRootCoordSpaceF(point);
}
bool RenderWidgetHostViewBase::IsRenderWidgetHostViewChildFrame() {