fune/gfx/layers/ipc/APZInputBridgeChild.h
Jamie Nicol aa73eaed41 Bug 1754332 - Add callback argument to APZInputBridge::ReceiveInputEvent. r=botond,geckoview-reviewers,agi
Rather than using a separate function
APZCTreeManager::AddInputBlockCallback(), allow an optional callback
argument to be passed to APZInputBridge::ReceiveInputEvent().

This avoids a race condition where the input block is processed before
the callback has a chance to be added to the input queue, meaning the
callback will never be fired. With the GPU process enabled the added
latency of adding the callback cross-process meant this occured
frequently, causing intermittent junit test failures.

This works similarily to before, with the in-process APZCTreeManager
implementation simply calling InputQueue::AddInputBlockCallback() and
the InputQueue will fire the callback when the input block has been
processed. For the cross-process implementation, APZInputBridgeChild
maintains a local map of the callbacks, and APZInputBridgeParent adds
an intermediate callback to its local InputQueue. This intermediate
callback will call APZInputBridgeParent::SendCallInputBlockCallback(),
which tells the APZInputBridgeChild to fire the real callback.

Care must be taken in both APZInputBridgeChild and Parent to only add
their respective callbacks if we determine that it is required, eg not
already handled by the root APZ.

Differential Revision: https://phabricator.services.mozilla.com/D138801
2022-02-18 07:29:10 +00:00

62 lines
2 KiB
C++

/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#ifndef mozilla_layers_APZInputBridgeChild_h
#define mozilla_layers_APZInputBridgeChild_h
#include "mozilla/layers/APZInputBridge.h"
#include "mozilla/layers/PAPZInputBridgeChild.h"
namespace mozilla {
namespace layers {
class APZInputBridgeChild : public PAPZInputBridgeChild, public APZInputBridge {
NS_INLINE_DECL_THREADSAFE_REFCOUNTING(APZInputBridgeChild, final)
public:
static RefPtr<APZInputBridgeChild> Create(
const uint64_t& aProcessToken,
Endpoint<PAPZInputBridgeChild>&& aEndpoint);
void Destroy();
APZEventResult ReceiveInputEvent(
InputData& aEvent,
InputBlockCallback&& aCallback = InputBlockCallback()) override;
mozilla::ipc::IPCResult RecvCallInputBlockCallback(
uint64_t aInputBlockId, const APZHandledResult& handledResult);
protected:
void ProcessUnhandledEvent(LayoutDeviceIntPoint* aRefPoint,
ScrollableLayerGuid* aOutTargetGuid,
uint64_t* aOutFocusSequenceNumber,
LayersId* aOutLayersId) override;
void UpdateWheelTransaction(
LayoutDeviceIntPoint aRefPoint, EventMessage aEventMessage,
const Maybe<ScrollableLayerGuid>& aTargetGuid) override;
void ActorDestroy(ActorDestroyReason aWhy) override;
explicit APZInputBridgeChild(const uint64_t& aProcessToken);
virtual ~APZInputBridgeChild();
private:
void Open(Endpoint<PAPZInputBridgeChild>&& aEndpoint);
bool mIsOpen;
uint64_t mProcessToken;
using InputBlockCallbackMap =
std::unordered_map<uint64_t, InputBlockCallback>;
InputBlockCallbackMap mInputBlockCallbacks;
};
} // namespace layers
} // namespace mozilla
#endif // mozilla_layers_APZInputBridgeChild_h