1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 /* vim: set ts=8 sts=2 et sw=2 tw=80: */
3 /* This Source Code Form is subject to the terms of the Mozilla Public
4 * License, v. 2.0. If a copy of the MPL was not distributed with this
5 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
7 #include "mozilla/layers/APZInputBridgeChild.h"
9 #include "InputData.h" // for InputData, etc
10 #include "mozilla/gfx/GPUProcessManager.h"
11 #include "mozilla/ipc/Endpoint.h"
12 #include "mozilla/layers/APZThreadUtils.h"
13 #include "mozilla/layers/SynchronousTask.h"
19 RefPtr
<APZInputBridgeChild
> APZInputBridgeChild::Create(
20 const uint64_t& aProcessToken
, Endpoint
<PAPZInputBridgeChild
>&& aEndpoint
) {
21 RefPtr
<APZInputBridgeChild
> child
= new APZInputBridgeChild(aProcessToken
);
23 MOZ_ASSERT(APZThreadUtils::IsControllerThreadAlive());
25 APZThreadUtils::RunOnControllerThread(
26 NewRunnableMethod
<Endpoint
<PAPZInputBridgeChild
>&&>(
27 "layers::APZInputBridgeChild::Open", child
,
28 &APZInputBridgeChild::Open
, std::move(aEndpoint
)));
33 APZInputBridgeChild::APZInputBridgeChild(const uint64_t& aProcessToken
)
34 : mIsOpen(false), mProcessToken(aProcessToken
) {
35 MOZ_ASSERT(XRE_IsParentProcess());
36 MOZ_ASSERT(NS_IsMainThread());
39 APZInputBridgeChild::~APZInputBridgeChild() = default;
41 void APZInputBridgeChild::Open(Endpoint
<PAPZInputBridgeChild
>&& aEndpoint
) {
42 APZThreadUtils::AssertOnControllerThread();
44 mIsOpen
= aEndpoint
.Bind(this);
47 // The GPU Process Manager might be gone if we receive ActorDestroy very
49 if (gfx::GPUProcessManager
* gpm
= gfx::GPUProcessManager::Get()) {
50 gpm
->NotifyRemoteActorDestroyed(mProcessToken
);
56 void APZInputBridgeChild::Destroy() {
57 MOZ_ASSERT(XRE_IsParentProcess());
58 MOZ_ASSERT(NS_IsMainThread());
60 // Destroy will get called from the main thread, so we must synchronously
61 // dispatch to the controller thread to close the bridge.
62 layers::SynchronousTask
task("layers::APZInputBridgeChild::Destroy");
63 APZThreadUtils::RunOnControllerThread(
64 NS_NewRunnableFunction("layers::APZInputBridgeChild::Destroy", [&]() {
65 APZThreadUtils::AssertOnControllerThread();
66 AutoCompleteTask
complete(&task
);
68 // Clear the process token so that we don't notify the GPUProcessManager
69 // about an abnormal shutdown, thereby tearing down the GPU process.
73 PAPZInputBridgeChild::Close();
81 void APZInputBridgeChild::ActorDestroy(ActorDestroyReason aWhy
) {
85 gfx::GPUProcessManager::Get()->NotifyRemoteActorDestroyed(mProcessToken
);
90 APZEventResult
APZInputBridgeChild::ReceiveInputEvent(
91 InputData
& aEvent
, InputBlockCallback
&& aCallback
) {
93 APZThreadUtils::AssertOnControllerThread();
96 switch (aEvent
.mInputType
) {
97 case MULTITOUCH_INPUT
: {
98 MultiTouchInput
& event
= aEvent
.AsMultiTouchInput();
99 MultiTouchInput processedEvent
;
101 SendReceiveMultiTouchInputEvent(event
, !!aCallback
, &res
,
104 event
= processedEvent
;
108 MouseInput
& event
= aEvent
.AsMouseInput();
109 MouseInput processedEvent
;
111 SendReceiveMouseInputEvent(event
, !!aCallback
, &res
, &processedEvent
);
113 event
= processedEvent
;
116 case PANGESTURE_INPUT
: {
117 PanGestureInput
& event
= aEvent
.AsPanGestureInput();
118 PanGestureInput processedEvent
;
120 SendReceivePanGestureInputEvent(event
, !!aCallback
, &res
,
123 event
= processedEvent
;
126 case PINCHGESTURE_INPUT
: {
127 PinchGestureInput
& event
= aEvent
.AsPinchGestureInput();
128 PinchGestureInput processedEvent
;
130 SendReceivePinchGestureInputEvent(event
, !!aCallback
, &res
,
133 event
= processedEvent
;
136 case TAPGESTURE_INPUT
: {
137 TapGestureInput
& event
= aEvent
.AsTapGestureInput();
138 TapGestureInput processedEvent
;
140 SendReceiveTapGestureInputEvent(event
, !!aCallback
, &res
,
143 event
= processedEvent
;
146 case SCROLLWHEEL_INPUT
: {
147 ScrollWheelInput
& event
= aEvent
.AsScrollWheelInput();
148 ScrollWheelInput processedEvent
;
150 SendReceiveScrollWheelInputEvent(event
, !!aCallback
, &res
,
153 event
= processedEvent
;
156 case KEYBOARD_INPUT
: {
157 KeyboardInput
& event
= aEvent
.AsKeyboardInput();
158 KeyboardInput processedEvent
;
160 SendReceiveKeyboardInputEvent(event
, !!aCallback
, &res
, &processedEvent
);
162 event
= processedEvent
;
166 MOZ_ASSERT_UNREACHABLE("Invalid InputData type.");
167 res
.SetStatusAsConsumeNoDefault();
172 if (aCallback
&& res
.WillHaveDelayedResult()) {
173 mInputBlockCallbacks
.emplace(res
.mInputBlockId
, std::move(aCallback
));
179 mozilla::ipc::IPCResult
APZInputBridgeChild::RecvCallInputBlockCallback(
180 uint64_t aInputBlockId
, const APZHandledResult
& aHandledResult
) {
181 auto it
= mInputBlockCallbacks
.find(aInputBlockId
);
182 if (it
!= mInputBlockCallbacks
.end()) {
183 it
->second(aInputBlockId
, aHandledResult
);
184 // The callback is one-shot; discard it after calling it.
185 mInputBlockCallbacks
.erase(it
);
191 void APZInputBridgeChild::ProcessUnhandledEvent(
192 LayoutDeviceIntPoint
* aRefPoint
, ScrollableLayerGuid
* aOutTargetGuid
,
193 uint64_t* aOutFocusSequenceNumber
, LayersId
* aOutLayersId
) {
195 APZThreadUtils::AssertOnControllerThread();
197 SendProcessUnhandledEvent(*aRefPoint
, aRefPoint
, aOutTargetGuid
,
198 aOutFocusSequenceNumber
, aOutLayersId
);
201 void APZInputBridgeChild::UpdateWheelTransaction(
202 LayoutDeviceIntPoint aRefPoint
, EventMessage aEventMessage
,
203 const Maybe
<ScrollableLayerGuid
>& aTargetGuid
) {
205 APZThreadUtils::AssertOnControllerThread();
207 SendUpdateWheelTransaction(aRefPoint
, aEventMessage
, aTargetGuid
);
210 } // namespace layers
211 } // namespace mozilla