Bug 1858610 - Move HandleTap from the APZCTreeManager to the InputBridge protocol. r=botond

The HandleTap message should be part of the InputBridge protocol to
ensure that the synthesized click events are sent to content after the
corresponding touch-end.

Differential Revision: https://phabricator.services.mozilla.com/D203468
This commit is contained in:
Dan Robertson 2024-04-18 15:46:23 +00:00
parent 286db30f2d
commit d497db15e7
13 changed files with 192 additions and 94 deletions

View file

@ -24,14 +24,13 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=1285070
{"file": "helper_bug1682170_pointercancel_on_touchaction_pinchzoom.html", {"file": "helper_bug1682170_pointercancel_on_touchaction_pinchzoom.html",
"prefs": touch_action_prefs}, "prefs": touch_action_prefs},
{"file": "helper_bug1719855_pointercancel_on_touchmove_after_contextmenu_prevented.html"}, {"file": "helper_bug1719855_pointercancel_on_touchmove_after_contextmenu_prevented.html"},
{"file": "helper_bug1285070.html"},
{"file": "helper_bug1299195.html", "prefs": [["dom.meta-viewport.enabled", isMac]]},
]; ];
if (getPlatform() != "android") { if (getPlatform() != "android") {
// Bug 1858610: these subtests are flaky on Android. // Bug 1858610: these subtests are flaky on Android.
subtests.push( subtests.push({"file": "helper_bug1502010_unconsumed_pan.html"});
{"file": "helper_bug1285070.html"},
{"file": "helper_bug1299195.html", "prefs": [["dom.meta-viewport.enabled", isMac]]},
{"file": "helper_bug1502010_unconsumed_pan.html"}
)
} }
if (isApzEnabled()) { if (isApzEnabled()) {

View file

@ -31,6 +31,9 @@ void APZCTreeManagerChild::SetCompositorSession(
// we're setting mCompositorSession or we're clearing it). // we're setting mCompositorSession or we're clearing it).
MOZ_ASSERT(!mCompositorSession ^ !aSession); MOZ_ASSERT(!mCompositorSession ^ !aSession);
mCompositorSession = aSession; mCompositorSession = aSession;
if (mInputBridge) {
mInputBridge->SetCompositorSession(aSession);
}
} }
void APZCTreeManagerChild::SetInputBridge(APZInputBridgeChild* aInputBridge) { void APZCTreeManagerChild::SetInputBridge(APZInputBridgeChild* aInputBridge) {
@ -143,45 +146,6 @@ void APZCTreeManagerChild::ActorDestroy(ActorDestroyReason aWhy) {
mIPCOpen = false; mIPCOpen = false;
} }
mozilla::ipc::IPCResult APZCTreeManagerChild::RecvHandleTap(
const TapType& aType, const LayoutDevicePoint& aPoint,
const Modifiers& aModifiers, const ScrollableLayerGuid& aGuid,
const uint64_t& aInputBlockId,
const Maybe<DoubleTapToZoomMetrics>& aDoubleTapToZoomMetrics) {
MOZ_ASSERT(XRE_IsParentProcess());
if (mCompositorSession &&
mCompositorSession->RootLayerTreeId() == aGuid.mLayersId &&
mCompositorSession->GetContentController()) {
RefPtr<GeckoContentController> controller =
mCompositorSession->GetContentController();
controller->HandleTap(aType, aPoint, aModifiers, aGuid, aInputBlockId,
aDoubleTapToZoomMetrics);
return IPC_OK();
}
dom::BrowserParent* tab =
dom::BrowserParent::GetBrowserParentFromLayersId(aGuid.mLayersId);
if (tab) {
#ifdef MOZ_WIDGET_ANDROID
// On Android, touch events are dispatched from the UI thread to the main
// thread using the Android priority queue. It is possible that this tap has
// made it to the GPU process and back before they have been processed. We
// must therefore dispatch this message to the same queue, otherwise the tab
// may receive the tap event before the touch events that synthesized it.
mozilla::jni::DispatchToGeckoPriorityQueue(
NewRunnableMethod<TapType, LayoutDevicePoint, Modifiers,
ScrollableLayerGuid, uint64_t,
Maybe<DoubleTapToZoomMetrics>>(
"dom::BrowserParent::SendHandleTap", tab,
&dom::BrowserParent::SendHandleTap, aType, aPoint, aModifiers,
aGuid, aInputBlockId, aDoubleTapToZoomMetrics));
#else
tab->SendHandleTap(aType, aPoint, aModifiers, aGuid, aInputBlockId,
aDoubleTapToZoomMetrics);
#endif
}
return IPC_OK();
}
mozilla::ipc::IPCResult APZCTreeManagerChild::RecvNotifyPinchGesture( mozilla::ipc::IPCResult APZCTreeManagerChild::RecvNotifyPinchGesture(
const PinchGestureType& aType, const ScrollableLayerGuid& aGuid, const PinchGestureType& aType, const ScrollableLayerGuid& aGuid,
const LayoutDevicePoint& aFocusPoint, const LayoutDeviceCoord& aSpanChange, const LayoutDevicePoint& aFocusPoint, const LayoutDeviceCoord& aSpanChange,

View file

@ -73,13 +73,6 @@ class APZCTreeManagerChild : public IAPZCTreeManager,
void ActorDestroy(ActorDestroyReason aWhy) override; void ActorDestroy(ActorDestroyReason aWhy) override;
protected: protected:
MOZ_CAN_RUN_SCRIPT_BOUNDARY
mozilla::ipc::IPCResult RecvHandleTap(
const TapType& aType, const LayoutDevicePoint& aPoint,
const Modifiers& aModifiers, const ScrollableLayerGuid& aGuid,
const uint64_t& aInputBlockId,
const Maybe<DoubleTapToZoomMetrics>& aDoubleTapToZoomMetrics);
mozilla::ipc::IPCResult RecvNotifyPinchGesture( mozilla::ipc::IPCResult RecvNotifyPinchGesture(
const PinchGestureType& aType, const ScrollableLayerGuid& aGuid, const PinchGestureType& aType, const ScrollableLayerGuid& aGuid,
const LayoutDevicePoint& aFocusPoint, const LayoutDevicePoint& aFocusPoint,

View file

@ -12,6 +12,14 @@
#include "mozilla/layers/APZThreadUtils.h" #include "mozilla/layers/APZThreadUtils.h"
#include "mozilla/layers/SynchronousTask.h" #include "mozilla/layers/SynchronousTask.h"
#include "mozilla/layers/GeckoContentController.h" // for GeckoContentController
#include "mozilla/layers/DoubleTapToZoom.h" // for DoubleTapToZoomMetrics
#include "mozilla/layers/RemoteCompositorSession.h" // for RemoteCompositorSession
#include "mozilla/dom/BrowserParent.h" // for BrowserParent
#ifdef MOZ_WIDGET_ANDROID
# include "mozilla/jni/Utils.h" // for DispatchToGeckoPriorityQueue
#endif
namespace mozilla { namespace mozilla {
namespace layers { namespace layers {
@ -31,13 +39,20 @@ RefPtr<APZInputBridgeChild> APZInputBridgeChild::Create(
} }
APZInputBridgeChild::APZInputBridgeChild(const uint64_t& aProcessToken) APZInputBridgeChild::APZInputBridgeChild(const uint64_t& aProcessToken)
: mIsOpen(false), mProcessToken(aProcessToken) { : mIsOpen(false),
mProcessToken(aProcessToken),
mCompositorSession(nullptr) {
MOZ_ASSERT(XRE_IsParentProcess()); MOZ_ASSERT(XRE_IsParentProcess());
MOZ_ASSERT(NS_IsMainThread()); MOZ_ASSERT(NS_IsMainThread());
} }
APZInputBridgeChild::~APZInputBridgeChild() = default; APZInputBridgeChild::~APZInputBridgeChild() = default;
void APZInputBridgeChild::SetCompositorSession(
RemoteCompositorSession* aSession) {
mCompositorSession = aSession;
}
void APZInputBridgeChild::Open(Endpoint<PAPZInputBridgeChild>&& aEndpoint) { void APZInputBridgeChild::Open(Endpoint<PAPZInputBridgeChild>&& aEndpoint) {
APZThreadUtils::AssertOnControllerThread(); APZThreadUtils::AssertOnControllerThread();
@ -176,6 +191,63 @@ APZEventResult APZInputBridgeChild::ReceiveInputEvent(
return res; return res;
} }
void APZInputBridgeChild::HandleTapOnMainThread(
const TapType& aType, const LayoutDevicePoint& aPoint,
const Modifiers& aModifiers, const ScrollableLayerGuid& aGuid,
const uint64_t& aInputBlockId,
const Maybe<DoubleTapToZoomMetrics>& aDoubleTapToZoomMetrics) {
if (mCompositorSession &&
mCompositorSession->RootLayerTreeId() == aGuid.mLayersId &&
mCompositorSession->GetContentController()) {
RefPtr<GeckoContentController> controller =
mCompositorSession->GetContentController();
controller->HandleTap(aType, aPoint, aModifiers, aGuid, aInputBlockId,
aDoubleTapToZoomMetrics);
return;
}
dom::BrowserParent* tab =
dom::BrowserParent::GetBrowserParentFromLayersId(aGuid.mLayersId);
if (tab) {
#ifdef MOZ_WIDGET_ANDROID
// On Android, touch events are dispatched from the UI thread to the main
// thread using the Android priority queue. It is possible that this tap has
// made it to the GPU process and back before they have been processed. We
// must therefore dispatch this message to the same queue, otherwise the tab
// may receive the tap event before the touch events that synthesized it.
mozilla::jni::DispatchToGeckoPriorityQueue(
NewRunnableMethod<TapType, LayoutDevicePoint, Modifiers,
ScrollableLayerGuid, uint64_t,
Maybe<DoubleTapToZoomMetrics>>(
"dom::BrowserParent::SendHandleTap", tab,
&dom::BrowserParent::SendHandleTap, aType, aPoint, aModifiers,
aGuid, aInputBlockId, aDoubleTapToZoomMetrics));
#else
tab->SendHandleTap(aType, aPoint, aModifiers, aGuid, aInputBlockId,
aDoubleTapToZoomMetrics);
#endif
}
}
mozilla::ipc::IPCResult APZInputBridgeChild::RecvHandleTap(
const TapType& aType, const LayoutDevicePoint& aPoint,
const Modifiers& aModifiers, const ScrollableLayerGuid& aGuid,
const uint64_t& aInputBlockId,
const Maybe<DoubleTapToZoomMetrics>& aDoubleTapToZoomMetrics) {
if (NS_IsMainThread()) {
HandleTapOnMainThread(aType, aPoint, aModifiers, aGuid, aInputBlockId,
aDoubleTapToZoomMetrics);
} else {
NS_DispatchToMainThread(
NewRunnableMethod<TapType, LayoutDevicePoint, Modifiers,
ScrollableLayerGuid, uint64_t,
Maybe<DoubleTapToZoomMetrics>>(
"layers::APZInputBridgeChild::HandleTapOnMainThread", this,
&APZInputBridgeChild::HandleTapOnMainThread, aType, aPoint,
aModifiers, aGuid, aInputBlockId, aDoubleTapToZoomMetrics));
}
return IPC_OK();
}
mozilla::ipc::IPCResult APZInputBridgeChild::RecvCallInputBlockCallback( mozilla::ipc::IPCResult APZInputBridgeChild::RecvCallInputBlockCallback(
uint64_t aInputBlockId, const APZHandledResult& aHandledResult) { uint64_t aInputBlockId, const APZHandledResult& aHandledResult) {
auto it = mInputBlockCallbacks.find(aInputBlockId); auto it = mInputBlockCallbacks.find(aInputBlockId);

View file

@ -10,11 +10,16 @@
#include "mozilla/layers/APZInputBridge.h" #include "mozilla/layers/APZInputBridge.h"
#include "mozilla/layers/PAPZInputBridgeChild.h" #include "mozilla/layers/PAPZInputBridgeChild.h"
#include "mozilla/layers/GeckoContentControllerTypes.h"
namespace mozilla { namespace mozilla {
namespace layers { namespace layers {
class RemoteCompositorSession;
class APZInputBridgeChild : public PAPZInputBridgeChild, public APZInputBridge { class APZInputBridgeChild : public PAPZInputBridgeChild, public APZInputBridge {
NS_INLINE_DECL_THREADSAFE_REFCOUNTING(APZInputBridgeChild, final) NS_INLINE_DECL_THREADSAFE_REFCOUNTING(APZInputBridgeChild, final)
using TapType = GeckoContentController_TapType;
public: public:
static RefPtr<APZInputBridgeChild> Create( static RefPtr<APZInputBridgeChild> Create(
@ -23,10 +28,19 @@ class APZInputBridgeChild : public PAPZInputBridgeChild, public APZInputBridge {
void Destroy(); void Destroy();
void SetCompositorSession(RemoteCompositorSession* aSession);
APZEventResult ReceiveInputEvent( APZEventResult ReceiveInputEvent(
InputData& aEvent, InputData& aEvent,
InputBlockCallback&& aCallback = InputBlockCallback()) override; InputBlockCallback&& aCallback = InputBlockCallback()) override;
MOZ_CAN_RUN_SCRIPT_BOUNDARY
mozilla::ipc::IPCResult RecvHandleTap(
const TapType& aType, const LayoutDevicePoint& aPoint,
const Modifiers& aModifiers, const ScrollableLayerGuid& aGuid,
const uint64_t& aInputBlockId,
const Maybe<DoubleTapToZoomMetrics>& aDoubleTapToZoomMetrics);
mozilla::ipc::IPCResult RecvCallInputBlockCallback( mozilla::ipc::IPCResult RecvCallInputBlockCallback(
uint64_t aInputBlockId, const APZHandledResult& handledResult); uint64_t aInputBlockId, const APZHandledResult& handledResult);
@ -48,8 +62,16 @@ class APZInputBridgeChild : public PAPZInputBridgeChild, public APZInputBridge {
private: private:
void Open(Endpoint<PAPZInputBridgeChild>&& aEndpoint); void Open(Endpoint<PAPZInputBridgeChild>&& aEndpoint);
MOZ_CAN_RUN_SCRIPT_BOUNDARY
void HandleTapOnMainThread(
const TapType& aType, const LayoutDevicePoint& aPoint,
const Modifiers& aModifiers, const ScrollableLayerGuid& aGuid,
const uint64_t& aInputBlockId,
const Maybe<DoubleTapToZoomMetrics>& aDoubleTapToZoomMetrics);
bool mIsOpen; bool mIsOpen;
uint64_t mProcessToken; uint64_t mProcessToken;
MOZ_NON_OWNING_REF RemoteCompositorSession* mCompositorSession = nullptr;
using InputBlockCallbackMap = using InputBlockCallbackMap =
std::unordered_map<uint64_t, InputBlockCallback>; std::unordered_map<uint64_t, InputBlockCallback>;

View file

@ -16,14 +16,15 @@ namespace mozilla {
namespace layers { namespace layers {
/* static */ /* static */
RefPtr<APZInputBridgeParent> APZInputBridgeParent::Create( APZInputBridgeParent* APZInputBridgeParent::Create(
const LayersId& aLayersId, Endpoint<PAPZInputBridgeParent>&& aEndpoint) { const LayersId& aLayersId, Endpoint<PAPZInputBridgeParent>&& aEndpoint) {
RefPtr<APZInputBridgeParent> parent = new APZInputBridgeParent(aLayersId); APZInputBridgeParent* parent = new APZInputBridgeParent(aLayersId);
if (!aEndpoint.Bind(parent)) { if (!aEndpoint.Bind(parent)) {
// We can't recover from this. // We can't recover from this.
MOZ_CRASH("Failed to bind APZInputBridgeParent to endpoint"); MOZ_CRASH("Failed to bind APZInputBridgeParent to endpoint");
} }
CompositorBridgeParent::SetAPZInputBridgeParent(aLayersId, parent);
return parent; return parent;
} }
@ -31,6 +32,7 @@ APZInputBridgeParent::APZInputBridgeParent(const LayersId& aLayersId) {
MOZ_ASSERT(XRE_IsGPUProcess()); MOZ_ASSERT(XRE_IsGPUProcess());
MOZ_ASSERT(NS_IsMainThread()); MOZ_ASSERT(NS_IsMainThread());
mLayersId = aLayersId;
mTreeManager = CompositorBridgeParent::GetAPZCTreeManager(aLayersId); mTreeManager = CompositorBridgeParent::GetAPZCTreeManager(aLayersId);
MOZ_ASSERT(mTreeManager); MOZ_ASSERT(mTreeManager);
} }
@ -205,6 +207,10 @@ mozilla::ipc::IPCResult APZInputBridgeParent::RecvProcessUnhandledEvent(
} }
void APZInputBridgeParent::ActorDestroy(ActorDestroyReason aWhy) { void APZInputBridgeParent::ActorDestroy(ActorDestroyReason aWhy) {
StaticMonitorAutoLock lock(CompositorBridgeParent::sIndirectLayerTreesLock);
CompositorBridgeParent::LayerTreeState& state =
CompositorBridgeParent::sIndirectLayerTrees[mLayersId];
state.mApzInputBridgeParent = nullptr;
// We shouldn't need it after this // We shouldn't need it after this
mTreeManager = nullptr; mTreeManager = nullptr;
} }

View file

@ -18,7 +18,7 @@ class APZInputBridgeParent : public PAPZInputBridgeParent {
NS_INLINE_DECL_REFCOUNTING(APZInputBridgeParent, final) NS_INLINE_DECL_REFCOUNTING(APZInputBridgeParent, final)
public: public:
static RefPtr<APZInputBridgeParent> Create( static APZInputBridgeParent* Create(
const LayersId& aLayersId, Endpoint<PAPZInputBridgeParent>&& aEndpoint); const LayersId& aLayersId, Endpoint<PAPZInputBridgeParent>&& aEndpoint);
mozilla::ipc::IPCResult RecvReceiveMultiTouchInputEvent( mozilla::ipc::IPCResult RecvReceiveMultiTouchInputEvent(
@ -67,6 +67,7 @@ class APZInputBridgeParent : public PAPZInputBridgeParent {
private: private:
RefPtr<IAPZCTreeManager> mTreeManager; RefPtr<IAPZCTreeManager> mTreeManager;
LayersId mLayersId;
}; };
} // namespace layers } // namespace layers

View file

@ -167,6 +167,7 @@ bool CompositorBridgeParentBase::DeallocShmem(ipc::Shmem& aShmem) {
CompositorBridgeParent::LayerTreeState::LayerTreeState() CompositorBridgeParent::LayerTreeState::LayerTreeState()
: mApzcTreeManagerParent(nullptr), : mApzcTreeManagerParent(nullptr),
mApzInputBridgeParent(nullptr),
mParent(nullptr), mParent(nullptr),
mContentCompositorBridgeParent(nullptr) {} mContentCompositorBridgeParent(nullptr) {}
@ -645,9 +646,21 @@ bool CompositorBridgeParent::DeallocPAPZCTreeManagerParent(
return true; return true;
} }
void CompositorBridgeParent::SetAPZInputBridgeParent(
const LayersId& aLayersId, APZInputBridgeParent* aInputBridgeParent) {
MOZ_RELEASE_ASSERT(XRE_IsGPUProcess());
MOZ_ASSERT(NS_IsMainThread());
StaticMonitorAutoLock lock(CompositorBridgeParent::sIndirectLayerTreesLock);
CompositorBridgeParent::LayerTreeState& state =
CompositorBridgeParent::sIndirectLayerTrees[aLayersId];
MOZ_ASSERT(!state.mApzInputBridgeParent);
state.mApzInputBridgeParent = aInputBridgeParent;
}
void CompositorBridgeParent::AllocateAPZCTreeManagerParent( void CompositorBridgeParent::AllocateAPZCTreeManagerParent(
const StaticMonitorAutoLock& aProofOfLayerTreeStateLock, const StaticMonitorAutoLock& aProofOfLayerTreeStateLock,
const LayersId& aLayersId, LayerTreeState& aState) { const LayersId& aLayersId, LayerTreeState& aState) {
MOZ_ASSERT(CompositorThreadHolder::IsInCompositorThread());
MOZ_ASSERT(aState.mParent == this); MOZ_ASSERT(aState.mParent == this);
MOZ_ASSERT(mApzcTreeManager); MOZ_ASSERT(mApzcTreeManager);
MOZ_ASSERT(mApzUpdater); MOZ_ASSERT(mApzUpdater);
@ -1712,6 +1725,15 @@ APZCTreeManagerParent* CompositorBridgeParent::GetApzcTreeManagerParentForRoot(
return state ? state->mApzcTreeManagerParent : nullptr; return state ? state->mApzcTreeManagerParent : nullptr;
} }
/* static */
APZInputBridgeParent* CompositorBridgeParent::GetApzInputBridgeParentForRoot(
LayersId aContentLayersId) {
StaticMonitorAutoLock lock(sIndirectLayerTreesLock);
CompositorBridgeParent::LayerTreeState* state =
GetStateForRoot(aContentLayersId, lock);
return state ? state->mApzInputBridgeParent : nullptr;
}
/* static */ /* static */
GeckoContentController* GeckoContentController*
CompositorBridgeParent::GetGeckoContentControllerForRoot( CompositorBridgeParent::GetGeckoContentControllerForRoot(

View file

@ -24,6 +24,7 @@
#include "mozilla/layers/ISurfaceAllocator.h" // for IShmemAllocator #include "mozilla/layers/ISurfaceAllocator.h" // for IShmemAllocator
#include "mozilla/layers/LayersTypes.h" #include "mozilla/layers/LayersTypes.h"
#include "mozilla/layers/PCompositorBridgeParent.h" #include "mozilla/layers/PCompositorBridgeParent.h"
#include "mozilla/layers/APZInputBridgeParent.h"
#include "mozilla/webrender/WebRenderTypes.h" #include "mozilla/webrender/WebRenderTypes.h"
namespace mozilla { namespace mozilla {
@ -394,6 +395,10 @@ class CompositorBridgeParent final : public CompositorBridgeParentBase,
~LayerTreeState(); ~LayerTreeState();
RefPtr<GeckoContentController> mController; RefPtr<GeckoContentController> mController;
APZCTreeManagerParent* mApzcTreeManagerParent; APZCTreeManagerParent* mApzcTreeManagerParent;
// The mApzInputBridgeParent is only populated for LayerTreeState
// objects corresponding to root LayerIds (one for each top-level
// window).
APZInputBridgeParent* mApzInputBridgeParent;
RefPtr<CompositorBridgeParent> mParent; RefPtr<CompositorBridgeParent> mParent;
RefPtr<WebRenderBridgeParent> mWrBridge; RefPtr<WebRenderBridgeParent> mWrBridge;
// Pointer to the ContentCompositorBridgeParent. Used by APZCs to share // Pointer to the ContentCompositorBridgeParent. Used by APZCs to share
@ -437,6 +442,13 @@ class CompositorBridgeParent final : public CompositorBridgeParentBase,
static GeckoContentController* GetGeckoContentControllerForRoot( static GeckoContentController* GetGeckoContentControllerForRoot(
LayersId aContentLayersId); LayersId aContentLayersId);
/**
* Same as the GetApzcTreeManagerParentForRoot function, but returns
* the APZInputBridge for the parent process.
*/
static APZInputBridgeParent* GetApzInputBridgeParentForRoot(
LayersId aContentLayersId);
/** /**
* Used by the profiler to denote when a vsync occured * Used by the profiler to denote when a vsync occured
*/ */
@ -454,6 +466,9 @@ class CompositorBridgeParent final : public CompositorBridgeParentBase,
const StaticMonitorAutoLock& aProofOfLayerTreeStateLock, const StaticMonitorAutoLock& aProofOfLayerTreeStateLock,
const LayersId& aLayersId, LayerTreeState& aLayerTreeStateToUpdate); const LayersId& aLayersId, LayerTreeState& aLayerTreeStateToUpdate);
static void SetAPZInputBridgeParent(const LayersId& aLayersId,
APZInputBridgeParent* aInputBridgeParent);
PAPZParent* AllocPAPZParent(const LayersId& aLayersId) override; PAPZParent* AllocPAPZParent(const LayersId& aLayersId) override;
bool DeallocPAPZParent(PAPZParent* aActor) override; bool DeallocPAPZParent(PAPZParent* aActor) override;

View file

@ -80,10 +80,6 @@ parent:
child: child:
async HandleTap(GeckoContentController_TapType aType, LayoutDevicePoint point, Modifiers aModifiers,
ScrollableLayerGuid aGuid, uint64_t aInputBlockId,
DoubleTapToZoomMetrics? aDoubleTapToZoomMetrics);
async NotifyPinchGesture(PinchGestureType aType, ScrollableLayerGuid aGuid, async NotifyPinchGesture(PinchGestureType aType, ScrollableLayerGuid aGuid,
LayoutDevicePoint aFocusPoint, LayoutDeviceCoord aSpanChange, LayoutDevicePoint aFocusPoint, LayoutDeviceCoord aSpanChange,
Modifiers aModifiers); Modifiers aModifiers);

View file

@ -6,11 +6,15 @@
include "ipc/nsGUIEventIPC.h"; include "ipc/nsGUIEventIPC.h";
using mozilla::LayoutDeviceIntPoint from "Units.h"; using mozilla::LayoutDeviceIntPoint from "Units.h";
using mozilla::LayoutDevicePoint from "Units.h";
using mozilla::layers::GeckoContentController_TapType from "mozilla/layers/GeckoContentControllerTypes.h";
using mozilla::layers::DoubleTapToZoomMetrics from "mozilla/layers/DoubleTapToZoom.h";
using struct mozilla::layers::ScrollableLayerGuid from "mozilla/layers/ScrollableLayerGuid.h"; using struct mozilla::layers::ScrollableLayerGuid from "mozilla/layers/ScrollableLayerGuid.h";
using struct mozilla::layers::APZEventResult from "mozilla/layers/APZInputBridge.h"; using struct mozilla::layers::APZEventResult from "mozilla/layers/APZInputBridge.h";
using struct mozilla::layers::APZHandledResult from "mozilla/layers/APZInputBridge.h"; using struct mozilla::layers::APZHandledResult from "mozilla/layers/APZInputBridge.h";
using mozilla::EventMessage from "mozilla/EventForwards.h"; using mozilla::EventMessage from "mozilla/EventForwards.h";
using mozilla::Modifiers from "mozilla/EventForwards.h";
using class mozilla::MultiTouchInput from "InputData.h"; using class mozilla::MultiTouchInput from "InputData.h";
using class mozilla::MouseInput from "InputData.h"; using class mozilla::MouseInput from "InputData.h";
using class mozilla::PanGestureInput from "InputData.h"; using class mozilla::PanGestureInput from "InputData.h";
@ -82,6 +86,10 @@ parent:
child: child:
async CallInputBlockCallback(uint64_t aInputBlockId, async CallInputBlockCallback(uint64_t aInputBlockId,
APZHandledResult aHandledResult); APZHandledResult aHandledResult);
async HandleTap(GeckoContentController_TapType aType, LayoutDevicePoint point,
Modifiers aModifiers, ScrollableLayerGuid aGuid,
uint64_t aInputBlockId, DoubleTapToZoomMetrics? aDoubleTapToZoomMetrics);
}; };
} // namespace gfx } // namespace gfx

View file

@ -62,7 +62,7 @@ void RemoteContentController::RequestContentRepaint(
} }
} }
void RemoteContentController::HandleTapOnMainThread( void RemoteContentController::HandleTapOnParentProcessMainThread(
TapType aTapType, LayoutDevicePoint aPoint, Modifiers aModifiers, TapType aTapType, LayoutDevicePoint aPoint, Modifiers aModifiers,
ScrollableLayerGuid aGuid, uint64_t aInputBlockId, ScrollableLayerGuid aGuid, uint64_t aInputBlockId,
const Maybe<DoubleTapToZoomMetrics>& aDoubleTapToZoomMetrics) { const Maybe<DoubleTapToZoomMetrics>& aDoubleTapToZoomMetrics) {
@ -78,20 +78,19 @@ void RemoteContentController::HandleTapOnMainThread(
} }
} }
void RemoteContentController::HandleTapOnCompositorThread( void RemoteContentController::HandleTapOnGPUProcessMainThread(
TapType aTapType, LayoutDevicePoint aPoint, Modifiers aModifiers, TapType aTapType, LayoutDevicePoint aPoint, Modifiers aModifiers,
ScrollableLayerGuid aGuid, uint64_t aInputBlockId, ScrollableLayerGuid aGuid, uint64_t aInputBlockId,
const Maybe<DoubleTapToZoomMetrics>& aDoubleTapToZoomMetrics) { const Maybe<DoubleTapToZoomMetrics>& aDoubleTapToZoomMetrics) {
MOZ_ASSERT(XRE_IsGPUProcess()); MOZ_ASSERT(XRE_IsGPUProcess());
MOZ_ASSERT(mCompositorThread->IsOnCurrentThread()); MOZ_ASSERT(NS_IsMainThread());
// The raw pointer to APZCTreeManagerParent is ok here because we are on // Send a message to the controller thread to handle the single-tap gesture.
// the compositor thread. APZInputBridgeParent* apzib =
APZCTreeManagerParent* apzctmp = CompositorBridgeParent::GetApzInputBridgeParentForRoot(aGuid.mLayersId);
CompositorBridgeParent::GetApzcTreeManagerParentForRoot(aGuid.mLayersId); if (apzib) {
if (apzctmp) { Unused << apzib->SendHandleTap(aTapType, aPoint, aModifiers, aGuid,
Unused << apzctmp->SendHandleTap(aTapType, aPoint, aModifiers, aGuid, aInputBlockId, aDoubleTapToZoomMetrics);
aInputBlockId, aDoubleTapToZoomMetrics);
} }
} }
@ -103,19 +102,18 @@ void RemoteContentController::HandleTap(
APZThreadUtils::AssertOnControllerThread(); APZThreadUtils::AssertOnControllerThread();
if (XRE_GetProcessType() == GeckoProcessType_GPU) { if (XRE_GetProcessType() == GeckoProcessType_GPU) {
if (mCompositorThread->IsOnCurrentThread()) { if (NS_IsMainThread()) {
HandleTapOnCompositorThread(aTapType, aPoint, aModifiers, aGuid, HandleTapOnGPUProcessMainThread(aTapType, aPoint, aModifiers, aGuid,
aInputBlockId, aDoubleTapToZoomMetrics); aInputBlockId, aDoubleTapToZoomMetrics);
} else { } else {
// We have to send messages from the compositor thread NS_DispatchToMainThread(NewRunnableMethod<TapType, LayoutDevicePoint,
mCompositorThread->Dispatch( Modifiers, ScrollableLayerGuid,
NewRunnableMethod<TapType, LayoutDevicePoint, Modifiers, uint64_t,
ScrollableLayerGuid, uint64_t, Maybe<DoubleTapToZoomMetrics>>(
Maybe<DoubleTapToZoomMetrics>>( "layers::RemoteContentController::HandleTapOnGPUProcessMainThread",
"layers::RemoteContentController::HandleTapOnCompositorThread", this, &RemoteContentController::HandleTapOnGPUProcessMainThread,
this, &RemoteContentController::HandleTapOnCompositorThread, aTapType, aPoint, aModifiers, aGuid, aInputBlockId,
aTapType, aPoint, aModifiers, aGuid, aInputBlockId, aDoubleTapToZoomMetrics));
aDoubleTapToZoomMetrics));
} }
return; return;
} }
@ -123,8 +121,8 @@ void RemoteContentController::HandleTap(
MOZ_ASSERT(XRE_IsParentProcess()); MOZ_ASSERT(XRE_IsParentProcess());
if (NS_IsMainThread()) { if (NS_IsMainThread()) {
HandleTapOnMainThread(aTapType, aPoint, aModifiers, aGuid, aInputBlockId, HandleTapOnParentProcessMainThread(aTapType, aPoint, aModifiers, aGuid,
aDoubleTapToZoomMetrics); aInputBlockId, aDoubleTapToZoomMetrics);
} else { } else {
// We must be on Android, running on the Java UI thread // We must be on Android, running on the Java UI thread
#ifndef MOZ_WIDGET_ANDROID #ifndef MOZ_WIDGET_ANDROID
@ -138,13 +136,15 @@ void RemoteContentController::HandleTap(
// using NS_DispatchToMainThread would post to a different message loop, // using NS_DispatchToMainThread would post to a different message loop,
// and introduces the possibility of this tap event getting processed // and introduces the possibility of this tap event getting processed
// out of order with respect to the touch events that synthesized it. // out of order with respect to the touch events that synthesized it.
mozilla::jni::DispatchToGeckoPriorityQueue( mozilla::jni::DispatchToGeckoPriorityQueue(NewRunnableMethod<
NewRunnableMethod<TapType, LayoutDevicePoint, Modifiers, TapType, LayoutDevicePoint,
ScrollableLayerGuid, uint64_t, Modifiers, ScrollableLayerGuid,
Maybe<DoubleTapToZoomMetrics>>( uint64_t,
"layers::RemoteContentController::HandleTapOnMainThread", this, Maybe<DoubleTapToZoomMetrics>>(
&RemoteContentController::HandleTapOnMainThread, aTapType, aPoint, "layers::RemoteContentController::HandleTapOnParentProcessMainThread",
aModifiers, aGuid, aInputBlockId, aDoubleTapToZoomMetrics)); this, &RemoteContentController::HandleTapOnParentProcessMainThread,
aTapType, aPoint, aModifiers, aGuid, aInputBlockId,
aDoubleTapToZoomMetrics));
#endif #endif
} }
} }

View file

@ -98,12 +98,12 @@ class RemoteContentController : public GeckoContentController,
nsCOMPtr<nsISerialEventTarget> mCompositorThread; nsCOMPtr<nsISerialEventTarget> mCompositorThread;
bool mCanSend; bool mCanSend;
void HandleTapOnMainThread( void HandleTapOnParentProcessMainThread(
TapType aType, LayoutDevicePoint aPoint, Modifiers aModifiers, TapType aTapType, LayoutDevicePoint aPoint, Modifiers aModifiers,
ScrollableLayerGuid aGuid, uint64_t aInputBlockId, ScrollableLayerGuid aGuid, uint64_t aInputBlockId,
const Maybe<DoubleTapToZoomMetrics>& aDoubleTapToZoomMetrics); const Maybe<DoubleTapToZoomMetrics>& aDoubleTapToZoomMetrics);
void HandleTapOnCompositorThread( void HandleTapOnGPUProcessMainThread(
TapType aType, LayoutDevicePoint aPoint, Modifiers aModifiers, TapType aTapType, LayoutDevicePoint aPoint, Modifiers aModifiers,
ScrollableLayerGuid aGuid, uint64_t aInputBlockId, ScrollableLayerGuid aGuid, uint64_t aInputBlockId,
const Maybe<DoubleTapToZoomMetrics>& aDoubleTapToZoomMetrics); const Maybe<DoubleTapToZoomMetrics>& aDoubleTapToZoomMetrics);
void NotifyPinchGestureOnCompositorThread( void NotifyPinchGestureOnCompositorThread(