Bug 1289650 - Move PAPZ from PContent to PCompositorBridge. r=kats

MozReview-Commit-ID: GzU1iEVqSx6
This commit is contained in:
Ryan Hunt 2016-08-01 23:59:00 -07:00
parent c0b437cb14
commit 76cbe77abe
23 changed files with 215 additions and 198 deletions

View File

@ -1161,19 +1161,6 @@ ContentChild::AllocPGMPServiceChild(mozilla::ipc::Transport* aTransport,
return GMPServiceChild::Create(aTransport, aOtherProcess);
}
PAPZChild*
ContentChild::AllocPAPZChild(const TabId& aTabId)
{
return APZChild::Create(aTabId);
}
bool
ContentChild::DeallocPAPZChild(PAPZChild* aActor)
{
delete aActor;
return true;
}
bool
ContentChild::RecvInitCompositor(Endpoint<PCompositorBridgeChild>&& aEndpoint)
{
@ -1392,6 +1379,13 @@ ContentChild::RecvSetProcessSandbox(const MaybeFileDesc& aBroker)
return true;
}
bool
ContentChild::RecvNotifyLayerAllocated(const dom::TabId& aTabId, const uint64_t& aLayersId)
{
APZChild* apz = APZChild::Create(aTabId);
return CompositorBridgeChild::Get()->SendPAPZConstructor(apz, aLayersId);
}
bool
ContentChild::RecvSpeakerManagerNotify()
{

View File

@ -143,11 +143,6 @@ public:
AllocPGMPServiceChild(mozilla::ipc::Transport* transport,
base::ProcessId otherProcess) override;
PAPZChild*
AllocPAPZChild(const TabId& aTabId) override;
bool
DeallocPAPZChild(PAPZChild* aActor) override;
bool
RecvInitCompositor(Endpoint<PCompositorBridgeChild>&& aEndpoint) override;
bool
@ -397,6 +392,8 @@ public:
virtual bool RecvSetConnectivity(const bool& connectivity) override;
virtual bool RecvNotifyLayerAllocated(const dom::TabId& aTabId, const uint64_t& aLayersId) override;
virtual bool RecvSpeakerManagerNotify() override;
virtual bool RecvBidiKeyboardNotify(const bool& isLangRTL,

View File

@ -1711,7 +1711,7 @@ ContentParent::AllocateLayerTreeId(ContentParent* aContent,
return false;
}
return gpu->UpdateRemoteContentController(*aId, aContent, aTabId, aTopLevel);
return aContent->SendNotifyLayerAllocated(aTabId, *aId);
}
bool
@ -2892,21 +2892,6 @@ ContentParent::AllocPGMPServiceParent(mozilla::ipc::Transport* aTransport,
return GMPServiceParent::Create(aTransport, aOtherProcess);
}
PAPZParent*
ContentParent::AllocPAPZParent(const TabId& aTabId)
{
// The PAPZParent should just be created in the main process and then an IPDL
// constructor message sent to hook it up.
MOZ_CRASH("This shouldn't be called");
return nullptr;
}
bool
ContentParent::DeallocPAPZParent(PAPZParent* aActor)
{
return true;
}
PBackgroundParent*
ContentParent::AllocPBackgroundParent(Transport* aTransport,
ProcessId aOtherProcess)

View File

@ -703,11 +703,6 @@ private:
AllocPGMPServiceParent(mozilla::ipc::Transport* aTransport,
base::ProcessId aOtherProcess) override;
PAPZParent*
AllocPAPZParent(const TabId& aTabId) override;
bool
DeallocPAPZParent(PAPZParent* aActor) override;
PSharedBufferManagerParent*
AllocPSharedBufferManagerParent(mozilla::ipc::Transport* aTranport,
base::ProcessId aOtherProcess) override;

View File

@ -4,7 +4,6 @@
* 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/. */
include protocol PAPZ;
include protocol PBackground;
include protocol PBlob;
include protocol PBluetooth;
@ -390,7 +389,6 @@ prio(normal upto urgent) sync protocol PContent
parent opens PGMPService;
child opens PBackground;
manages PAPZ;
manages PBlob;
manages PBluetooth;
manages PBrowser;
@ -484,6 +482,11 @@ child:
async PMemoryReportRequest(uint32_t generation, bool anonymize,
bool minimizeMemoryUsage, MaybeFileDesc DMDFile);
/**
* Sent to notify that aTabId has been allocated aLayersId
*/
async NotifyLayerAllocated(TabId aTabId, uint64_t aLayersId);
async SpeakerManagerNotify();
/**
@ -504,8 +507,6 @@ child:
async PTestShell();
async PAPZ(TabId tabId);
async RegisterChrome(ChromePackage[] packages, SubstitutionMapping[] substitutions,
OverrideMapping[] overrides, nsCString locale, bool reset);
async RegisterChromeItem(ChromeRegistryItem item);

View File

@ -565,19 +565,6 @@ GPUProcessManager::SwapLayerTreeObservers(uint64_t aLayer, uint64_t aOtherLayer)
CompositorBridgeParent::SwapLayerTreeObservers(aLayer, aOtherLayer);
}
bool
GPUProcessManager::UpdateRemoteContentController(uint64_t aLayersId,
dom::ContentParent* aContentParent,
const dom::TabId& aTabId,
dom::TabParent* aBrowserParent)
{
return CompositorBridgeParent::UpdateRemoteContentController(
aLayersId,
aContentParent,
aTabId,
aBrowserParent);
}
void
GPUProcessManager::EnsureVsyncIOThread()
{

View File

@ -115,18 +115,6 @@ public:
void RequestNotifyLayerTreeCleared(uint64_t aLayersId, CompositorUpdateObserver* aObserver);
void SwapLayerTreeObservers(uint64_t aLayer, uint64_t aOtherLayer);
// Creates a new RemoteContentController for aTabId. Should only be called on
// the main thread.
//
// aLayersId The layers id for the browser corresponding to aTabId.
// aContentParent The ContentParent for the process that the TabChild for
// aTabId lives in.
// aBrowserParent The toplevel TabParent for aTabId.
bool UpdateRemoteContentController(uint64_t aLayersId,
dom::ContentParent* aContentParent,
const dom::TabId& aTabId,
dom::TabParent* aBrowserParent);
void OnProcessLaunchComplete(GPUProcessHost* aHost) override;
void OnProcessUnexpectedShutdown(GPUProcessHost* aHost) override;

View File

@ -12,7 +12,6 @@
#include "mozilla/Assertions.h" // for MOZ_ASSERT_HELPER2
#include "mozilla/EventForwards.h" // for Modifiers
#include "nsISupportsImpl.h"
#include "ThreadSafeRefcountingWithMainThreadDestruction.h"
namespace mozilla {
@ -23,12 +22,7 @@ namespace layers {
class GeckoContentController
{
public:
/**
* At least one class deriving from GeckoContentController needs to do
* synchronous cleanup on the main thread, so we use
* NS_INLINE_DECL_THREADSAFE_REFCOUNTING_WITH_MAIN_THREAD_DESTRUCTION.
*/
NS_INLINE_DECL_THREADSAFE_REFCOUNTING_WITH_MAIN_THREAD_DESTRUCTION(GeckoContentController)
NS_INLINE_DECL_THREADSAFE_REFCOUNTING(GeckoContentController)
/**
* Requests a paint of the given FrameMetrics |aFrameMetrics| from Gecko.
@ -71,6 +65,16 @@ public:
*/
virtual void PostDelayedTask(already_AddRefed<Runnable> aRunnable, int aDelayMs) = 0;
/**
* Returns true if we are currently on the thread that can send repaint requests.
*/
virtual bool IsRepaintThread() = 0;
/**
* Runs the given task on the "repaint" thread.
*/
virtual void DispatchToRepaintThread(already_AddRefed<Runnable> aTask) = 0;
/**
* APZ uses |FrameMetrics::mCompositionBounds| for hit testing. Sometimes,
* widget code has knowledge of a touch-sensitive region that should

View File

@ -630,8 +630,8 @@ APZCTreeManager::FlushApzRepaints(uint64_t aLayersId)
const CompositorBridgeParent::LayerTreeState* state =
CompositorBridgeParent::GetIndirectShadowTree(aLayersId);
MOZ_ASSERT(state && state->mController);
NS_DispatchToMainThread(NewRunnableMethod(
state->mController, &GeckoContentController::NotifyFlushComplete));
state->mController->DispatchToRepaintThread(NewRunnableMethod(
state->mController, &GeckoContentController::NotifyFlushComplete));
}
nsEventStatus

View File

@ -2819,19 +2819,23 @@ int32_t AsyncPanZoomController::GetLastTouchIdentifier() const {
}
void AsyncPanZoomController::RequestContentRepaint(bool aUserAction) {
// Reinvoke this method on the main thread if it's not there already. It's
// Reinvoke this method on the repaint thread if it's not there already. It's
// important to do this before the call to CalculatePendingDisplayPort, so
// that CalculatePendingDisplayPort uses the most recent available version of
// mFrameMetrics, just before the paint request is dispatched to content.
if (!NS_IsMainThread()) {
RefPtr<GeckoContentController> controller = GetGeckoContentController();
if (!controller) {
return;
}
if (!controller->IsRepaintThread()) {
// use the local variable to resolve the function overload.
auto func = static_cast<void (AsyncPanZoomController::*)(bool)>
(&AsyncPanZoomController::RequestContentRepaint);
NS_DispatchToMainThread(NewRunnableMethod<bool>(this, func, aUserAction));
controller->DispatchToRepaintThread(NewRunnableMethod<bool>(this, func, aUserAction));
return;
}
MOZ_ASSERT(NS_IsMainThread());
MOZ_ASSERT(controller->IsRepaintThread());
ReentrantMonitorAutoEnter lock(mMonitor);
ParentLayerPoint velocity = GetVelocityVector();
@ -2857,7 +2861,11 @@ void
AsyncPanZoomController::RequestContentRepaint(const FrameMetrics& aFrameMetrics,
const ParentLayerPoint& aVelocity)
{
MOZ_ASSERT(NS_IsMainThread());
RefPtr<GeckoContentController> controller = GetGeckoContentController();
if (!controller) {
return;
}
MOZ_ASSERT(controller->IsRepaintThread());
// If we're trying to paint what we already think is painted, discard this
// request since it's a pointless paint.
@ -2881,11 +2889,6 @@ AsyncPanZoomController::RequestContentRepaint(const FrameMetrics& aFrameMetrics,
return;
}
RefPtr<GeckoContentController> controller = GetGeckoContentController();
if (!controller) {
return;
}
APZC_LOG_FM(aFrameMetrics, "%p requesting content repaint", this);
{ // scope lock
MutexAutoLock lock(mCheckerboardEventLock);
@ -3586,13 +3589,18 @@ void AsyncPanZoomController::ZoomToRect(CSSRect aRect, const uint32_t aFlags) {
endZoomToMetrics.SetUseDisplayPortMargins(true);
endZoomToMetrics.SetPaintRequestTime(TimeStamp::Now());
endZoomToMetrics.SetRepaintDrivenByUserAction(true);
if (NS_IsMainThread()) {
RefPtr<GeckoContentController> controller = GetGeckoContentController();
if (!controller) {
return;
}
if (controller->IsRepaintThread()) {
RequestContentRepaint(endZoomToMetrics, velocity);
} else {
// use a local var to resolve the function overload
auto func = static_cast<void (AsyncPanZoomController::*)(const FrameMetrics&, const ParentLayerPoint&)>
(&AsyncPanZoomController::RequestContentRepaint);
NS_DispatchToMainThread(
controller->DispatchToRepaintThread(
NewRunnableMethod<FrameMetrics, ParentLayerPoint>(
this, func, endZoomToMetrics, velocity));
}

View File

@ -82,6 +82,12 @@ public:
void PostDelayedTask(already_AddRefed<Runnable> aTask, int aDelayMs) {
RefPtr<Runnable> task = aTask;
}
bool IsRepaintThread() {
return NS_IsMainThread();
}
void DispatchToRepaintThread(already_AddRefed<Runnable> aTask) {
NS_DispatchToMainThread(Move(aTask));
}
MOCK_METHOD3(NotifyAPZStateChange, void(const ScrollableLayerGuid& aGuid, APZStateChange aChange, int aArg));
MOCK_METHOD0(NotifyFlushComplete, void());
};

View File

@ -50,7 +50,7 @@ ChromeProcessController::InitializeRoot()
void
ChromeProcessController::RequestContentRepaint(const FrameMetrics& aFrameMetrics)
{
MOZ_ASSERT(NS_IsMainThread());
MOZ_ASSERT(IsRepaintThread());
FrameMetrics metrics = aFrameMetrics;
if (metrics.IsRootContent()) {
@ -66,6 +66,18 @@ ChromeProcessController::PostDelayedTask(already_AddRefed<Runnable> aTask, int a
MessageLoop::current()->PostDelayedTask(Move(aTask), aDelayMs);
}
bool
ChromeProcessController::IsRepaintThread()
{
return NS_IsMainThread();
}
void
ChromeProcessController::DispatchToRepaintThread(already_AddRefed<Runnable> aTask)
{
NS_DispatchToMainThread(Move(aTask));
}
void
ChromeProcessController::Destroy()
{
@ -224,6 +236,7 @@ ChromeProcessController::NotifyMozMouseScrollEvent(const FrameMetrics::ViewID& a
void
ChromeProcessController::NotifyFlushComplete()
{
MOZ_ASSERT(NS_IsMainThread());
MOZ_ASSERT(IsRepaintThread());
APZCCallbackHelper::NotifyFlushComplete(GetPresShell());
}

View File

@ -40,6 +40,8 @@ public:
// GeckoContentController interface
virtual void RequestContentRepaint(const FrameMetrics& aFrameMetrics) override;
virtual void PostDelayedTask(already_AddRefed<Runnable> aTask, int aDelayMs) override;
virtual bool IsRepaintThread() override;
virtual void DispatchToRepaintThread(already_AddRefed<Runnable> aTask) override;
virtual void HandleTap(TapType aType,
const mozilla::LayoutDevicePoint& aPoint,
Modifiers aModifiers,

View File

@ -107,11 +107,22 @@ APZChild::RecvHandleTap(const TapType& aType,
const uint64_t& aInputBlockId,
const bool& aCallTakeFocusForClickFromTap)
{
mBrowser->HandleTap(aType, aPoint, aModifiers, aGuid,
mBrowser->HandleTap(aType, aPoint - mBrowser->GetChromeDisplacement(), aModifiers, aGuid,
aInputBlockId, aCallTakeFocusForClickFromTap);
return true;
}
bool
APZChild::RecvNotifyMozMouseScrollEvent(const uint64_t& aLayersId,
const ViewID& aScrollId,
const nsString& aEvent)
{
if (mBrowser) {
mBrowser->RecvMouseScrollTestEvent(aLayersId, aScrollId, aEvent);
}
return true;
}
bool
APZChild::RecvNotifyAPZStateChange(const ViewID& aViewId,
const APZStateChange& aChange,
@ -139,7 +150,6 @@ APZChild::RecvDestroy()
mBrowser->SetAPZChild(nullptr);
mBrowser = nullptr;
}
PAPZChild::Send__delete__(this);
return true;
}

View File

@ -37,6 +37,10 @@ public:
const uint64_t& aInputBlockId,
const bool& aCallTakeFocusForClickFromTap) override;
bool RecvNotifyMozMouseScrollEvent(const uint64_t& aLayersId,
const ViewID& aScrollId,
const nsString& aEvent) override;
bool RecvNotifyAPZStateChange(const ViewID& aViewId,
const APZStateChange& aChange,
const int& aArg) override;

View File

@ -13,6 +13,7 @@
#include "base/task.h" // for NewRunnableMethod, etc
#include "gfxPrefs.h"
#include "mozilla/layers/ImageBridgeChild.h"
#include "mozilla/layers/APZChild.h"
#include "mozilla/layers/IAPZCTreeManager.h"
#include "mozilla/layers/APZCTreeManagerChild.h"
#include "mozilla/layers/LayerTransactionChild.h"
@ -1036,6 +1037,21 @@ CompositorBridgeChild::AllocPAPZCTreeManagerChild(const uint64_t& aLayersId)
return child;
}
PAPZChild*
CompositorBridgeChild::AllocPAPZChild(const uint64_t& aLayersId)
{
// We send the constructor manually.
MOZ_CRASH("Should not be called");
return nullptr;
}
bool
CompositorBridgeChild::DeallocPAPZChild(PAPZChild* aActor)
{
delete aActor;
return true;
}
bool
CompositorBridgeChild::DeallocPAPZCTreeManagerChild(PAPZCTreeManagerChild* aActor)
{

View File

@ -216,6 +216,9 @@ public:
PAPZCTreeManagerChild* AllocPAPZCTreeManagerChild(const uint64_t& aLayersId) override;
bool DeallocPAPZCTreeManagerChild(PAPZCTreeManagerChild* aActor) override;
PAPZChild* AllocPAPZChild(const uint64_t& aLayersId) override;
bool DeallocPAPZChild(PAPZChild* aActor) override;
virtual ShmemAllocator* AsShmemAllocator() override { return this; }
void ProcessingError(Result aCode, const char* aReason) override;

View File

@ -25,7 +25,7 @@
#include "mozilla/AutoRestore.h" // for AutoRestore
#include "mozilla/ClearOnShutdown.h" // for ClearOnShutdown
#include "mozilla/DebugOnly.h" // for DebugOnly
#include "mozilla/dom/ContentParent.h"
#include "mozilla/dom/TabParent.h"
#include "mozilla/gfx/2D.h" // for DrawTarget
#include "mozilla/gfx/Point.h" // for IntSize
#include "mozilla/gfx/Rect.h" // for IntSize
@ -1365,6 +1365,18 @@ CompositorBridgeParent::DeallocPAPZCTreeManagerParent(PAPZCTreeManagerParent* aA
return false;
}
PAPZParent*
CompositorBridgeParent::AllocPAPZParent(const uint64_t& aLayersId)
{
return nullptr;
}
bool
CompositorBridgeParent::DeallocPAPZParent(PAPZParent* aActor)
{
return false;
}
bool
CompositorBridgeParent::RecvAsyncPanZoomEnabled(const uint64_t& aLayersId, bool* aHasAPZ)
{
@ -1776,29 +1788,6 @@ CompositorBridgeParent::NotifyChildCreated(uint64_t aChild)
sIndirectLayerTrees[aChild].mLayerManager = mLayerManager;
}
/* static */ bool
CompositorBridgeParent::UpdateRemoteContentController(uint64_t aLayersId,
dom::ContentParent* aContent,
const dom::TabId& aTabId,
dom::TabParent* aTopLevel)
{
MOZ_ASSERT(NS_IsMainThread());
MonitorAutoLock lock(*sIndirectLayerTreesLock);
LayerTreeState& state = sIndirectLayerTrees[aLayersId];
// RemoteContentController needs to know the layers id and the top level
// TabParent, so we pass that to its constructor here and then set up the
// PAPZ protocol by calling SendPAPZConstructor (and pass in the tab id for
// the PBrowser that it corresponds to).
RefPtr<RemoteContentController> controller =
new RemoteContentController(aLayersId, aTopLevel);
if (!aContent->SendPAPZConstructor(controller, aTabId)) {
return false;
}
state.mController = controller;
return true;
}
bool
CompositorBridgeParent::RecvAdoptChild(const uint64_t& child)
{
@ -2198,6 +2187,9 @@ public:
virtual PAPZCTreeManagerParent* AllocPAPZCTreeManagerParent(const uint64_t& aLayersId) override;
virtual bool DeallocPAPZCTreeManagerParent(PAPZCTreeManagerParent* aActor) override;
virtual PAPZParent* AllocPAPZParent(const uint64_t& aLayersId) override;
virtual bool DeallocPAPZParent(PAPZParent* aActor) override;
virtual CompositorBridgeParentIPCAllocator* AsCompositorBridgeParentIPCAllocator() override { return this; }
virtual void UpdatePaintTime(LayerTransactionParent* aLayerTree, const TimeDuration& aPaintTime) override {
@ -2583,6 +2575,31 @@ CrossProcessCompositorBridgeParent::DeallocPAPZCTreeManagerParent(PAPZCTreeManag
return true;
}
PAPZParent*
CrossProcessCompositorBridgeParent::AllocPAPZParent(const uint64_t& aLayersId)
{
// Check to see if this child process has access to this layer tree.
if (!LayerTreeOwnerTracker::Get()->IsMapped(aLayersId, OtherPid())) {
NS_ERROR("Unexpected layers id in AllocPAPZParent; dropping message...");
return nullptr;
}
RefPtr<RemoteContentController> controller = new RemoteContentController(aLayersId);
MonitorAutoLock lock(*sIndirectLayerTreesLock);
CompositorBridgeParent::LayerTreeState& state = sIndirectLayerTrees[aLayersId];
MOZ_ASSERT(!state.mController);
state.mController = controller;
return controller;
}
bool
CrossProcessCompositorBridgeParent::DeallocPAPZParent(PAPZParent* aActor)
{
return true;
}
bool
CrossProcessCompositorBridgeParent::RecvNotifyChildCreated(const uint64_t& child)
{

View File

@ -494,6 +494,9 @@ public:
PAPZCTreeManagerParent* AllocPAPZCTreeManagerParent(const uint64_t& aLayersId) override;
bool DeallocPAPZCTreeManagerParent(PAPZCTreeManagerParent* aActor) override;
PAPZParent* AllocPAPZParent(const uint64_t& aLayersId) override;
bool DeallocPAPZParent(PAPZParent* aActor) override;
bool RecvAsyncPanZoomEnabled(const uint64_t& aLayersId, bool* aHasAPZ) override;
RefPtr<APZCTreeManager> GetAPZCTreeManager();
@ -528,20 +531,6 @@ private:
static void RequestNotifyLayerTreeCleared(uint64_t aLayersId, CompositorUpdateObserver* aObserver);
static void SwapLayerTreeObservers(uint64_t aLayer, uint64_t aOtherLayer);
/**
* Creates a new RemoteContentController for aTabId. Should only be called on
* the main thread.
*
* aLayersId The layers id for the browser corresponding to aTabId.
* aContentParent The ContentParent for the process that the TabChild for
* aTabId lives in.
* aBrowserParent The toplevel TabParent for aTabId.
*/
static bool UpdateRemoteContentController(uint64_t aLayersId,
dom::ContentParent* aContentParent,
const dom::TabId& aTabId,
dom::TabParent* aBrowserParent);
protected:
// Protected destructor, to discourage deletion outside of Release():
virtual ~CompositorBridgeParent();

View File

@ -7,7 +7,7 @@
include "mozilla/GfxMessageUtils.h";
include protocol PContent;
include protocol PCompositorBridge;
using mozilla::LayoutDevicePoint from "Units.h";
using CSSRect from "Units.h";
@ -39,7 +39,7 @@ namespace layers {
*/
sync protocol PAPZ
{
manager PContent;
manager PCompositorBridge;
parent:
@ -57,6 +57,8 @@ child:
ScrollableLayerGuid aGuid, uint64_t aInputBlockId,
bool aCallTakeFocusForClickFromTap);
async NotifyMozMouseScrollEvent(uint64_t aLayersId, ViewID aScrollId, nsString aEvent);
async NotifyAPZStateChange(ViewID aViewId, APZStateChange aChange, int aArg);
async NotifyFlushComplete();

View File

@ -8,6 +8,7 @@
include LayersSurfaces;
include LayersMessages;
include PlatformWidgetTypes;
include protocol PAPZ;
include protocol PAPZCTreeManager;
include protocol PBrowser;
include protocol PCompositable;
@ -47,6 +48,7 @@ namespace layers {
*/
sync protocol PCompositorBridge
{
manages PAPZ;
manages PAPZCTreeManager;
// A Compositor manages a single Layer Manager (PLayerTransaction)
manages PLayerTransaction;
@ -125,6 +127,7 @@ parent:
sync AsyncPanZoomEnabled(uint64_t layersId) returns (bool aHasAPZ);
// Must be called after Initialize(), and only succeeds if AsyncPanZoomEnabled() is true.
async PAPZ(uint64_t layersId);
async PAPZCTreeManager(uint64_t layersId);
/**

View File

@ -28,14 +28,12 @@ using namespace mozilla::gfx;
static std::map<uint64_t, RefPtr<RemoteContentController>> sDestroyedControllers;
RemoteContentController::RemoteContentController(uint64_t aLayersId,
dom::TabParent* aBrowserParent)
: mUILoop(MessageLoop::current())
RemoteContentController::RemoteContentController(uint64_t aLayersId)
: mCompositorThread(MessageLoop::current())
, mLayersId(aLayersId)
, mBrowserParent(aBrowserParent)
, mCanSend(true)
, mMutex("RemoteContentController")
{
MOZ_ASSERT(NS_IsMainThread());
}
RemoteContentController::~RemoteContentController()
@ -45,8 +43,9 @@ RemoteContentController::~RemoteContentController()
void
RemoteContentController::RequestContentRepaint(const FrameMetrics& aFrameMetrics)
{
MOZ_ASSERT(NS_IsMainThread());
if (CanSend()) {
MOZ_ASSERT(IsRepaintThread());
if (mCanSend) {
Unused << SendRequestContentRepaint(aFrameMetrics);
}
}
@ -58,10 +57,9 @@ RemoteContentController::HandleTap(TapType aTapType,
const ScrollableLayerGuid& aGuid,
uint64_t aInputBlockId)
{
if (MessageLoop::current() != mUILoop) {
// We have to send this message from the "UI thread" (main
// thread).
mUILoop->PostTask(NewRunnableMethod<TapType, LayoutDevicePoint, Modifiers,
if (MessageLoop::current() != mCompositorThread) {
// We have to send messages from the compositor thread
mCompositorThread->PostTask(NewRunnableMethod<TapType, LayoutDevicePoint, Modifiers,
ScrollableLayerGuid, uint64_t>(this,
&RemoteContentController::HandleTap,
aTapType, aPoint, aModifiers, aGuid,
@ -70,18 +68,9 @@ RemoteContentController::HandleTap(TapType aTapType,
}
bool callTakeFocusForClickFromTap = (aTapType == TapType::eSingleTap);
if (callTakeFocusForClickFromTap && mBrowserParent) {
layout::RenderFrameParent* frame = mBrowserParent->GetRenderFrame();
if (frame && mLayersId == frame->GetLayersId()) {
// Avoid going over IPC and back for calling TakeFocusForClickFromTap,
// since the right RenderFrameParent is living in this process.
frame->TakeFocusForClickFromTap();
callTakeFocusForClickFromTap = false;
}
}
if (CanSend()) {
Unused << SendHandleTap(aTapType, mBrowserParent->AdjustTapToChildWidget(aPoint),
if (mCanSend) {
Unused << SendHandleTap(aTapType, aPoint,
aModifiers, aGuid, aInputBlockId, callTakeFocusForClickFromTap);
}
}
@ -92,11 +81,23 @@ RemoteContentController::PostDelayedTask(already_AddRefed<Runnable> aTask, int a
#ifdef MOZ_WIDGET_ANDROID
AndroidBridge::Bridge()->PostTaskToUiThread(Move(aTask), aDelayMs);
#else
(MessageLoop::current() ? MessageLoop::current() : mUILoop)->
(MessageLoop::current() ? MessageLoop::current() : mCompositorThread)->
PostDelayedTask(Move(aTask), aDelayMs);
#endif
}
bool
RemoteContentController::IsRepaintThread()
{
return MessageLoop::current() == mCompositorThread;
}
void
RemoteContentController::DispatchToRepaintThread(already_AddRefed<Runnable> aTask)
{
mCompositorThread->PostTask(Move(aTask));
}
bool
RemoteContentController::GetTouchSensitiveRegion(CSSRect* aOutRegion)
{
@ -114,15 +115,17 @@ RemoteContentController::NotifyAPZStateChange(const ScrollableLayerGuid& aGuid,
APZStateChange aChange,
int aArg)
{
if (MessageLoop::current() != mUILoop) {
mUILoop->PostTask(NewRunnableMethod<ScrollableLayerGuid,
if (MessageLoop::current() != mCompositorThread) {
// We have to send messages from the compositor thread
mCompositorThread->PostTask(NewRunnableMethod<ScrollableLayerGuid,
APZStateChange,
int>(this,
&RemoteContentController::NotifyAPZStateChange,
aGuid, aChange, aArg));
return;
}
if (CanSend()) {
if (mCanSend) {
Unused << SendNotifyAPZStateChange(aGuid.mScrollId, aChange, aArg);
}
}
@ -131,24 +134,26 @@ void
RemoteContentController::NotifyMozMouseScrollEvent(const FrameMetrics::ViewID& aScrollId,
const nsString& aEvent)
{
if (MessageLoop::current() != mUILoop) {
mUILoop->PostTask(NewRunnableMethod<FrameMetrics::ViewID,
if (MessageLoop::current() != mCompositorThread) {
// We have to send messages from the compositor thread
mCompositorThread->PostTask(NewRunnableMethod<FrameMetrics::ViewID,
nsString>(this,
&RemoteContentController::NotifyMozMouseScrollEvent,
aScrollId, aEvent));
return;
}
if (mBrowserParent) {
Unused << mBrowserParent->SendMouseScrollTestEvent(mLayersId, aScrollId, aEvent);
if (mCanSend) {
Unused << SendNotifyMozMouseScrollEvent(mLayersId, aScrollId, aEvent);
}
}
void
RemoteContentController::NotifyFlushComplete()
{
MOZ_ASSERT(NS_IsMainThread());
if (CanSend()) {
MOZ_ASSERT(IsRepaintThread());
if (mCanSend) {
Unused << SendNotifyFlushComplete();
}
}
@ -164,33 +169,26 @@ RemoteContentController::RecvUpdateHitRegion(const nsRegion& aRegion)
void
RemoteContentController::ActorDestroy(ActorDestroyReason aWhy)
{
mBrowserParent = nullptr;
mCanSend = false;
uint64_t key = mLayersId;
NS_DispatchToMainThread(NS_NewRunnableFunction([key]() {
// sDestroyedControllers may or may not contain the key, depending on
// whether or not SendDestroy() was successfully sent out or not.
sDestroyedControllers.erase(key);
}));
// sDestroyedControllers may or may not contain the key, depending on
// whether or not SendDestroy() was successfully sent out or not.
sDestroyedControllers.erase(mLayersId);
}
void
RemoteContentController::Destroy()
{
RefPtr<RemoteContentController> controller = this;
NS_DispatchToMainThread(NS_NewRunnableFunction([controller] {
if (controller->CanSend()) {
// Gfx code is done with this object, and it will probably get destroyed
// soon. However, if CanSend() is true, ActorDestroy has not yet been
// called, which means IPC code still has a handle to this object. We need
// to keep it alive until we get the ActorDestroy call, either via the
// __delete__ message or via IPC shutdown on our end.
uint64_t key = controller->mLayersId;
MOZ_ASSERT(sDestroyedControllers.find(key) == sDestroyedControllers.end());
sDestroyedControllers[key] = controller;
Unused << controller->SendDestroy();
}
}));
if (mCanSend) {
// Gfx code is done with this object, and it will probably get destroyed
// soon. However, if mCanSend is true, ActorDestroy has not yet been
// called, which means IPC code still has a handle to this object. We need
// to keep it alive until we get the ActorDestroy call, either via the
// __delete__ message or via IPC shutdown on our end.
MOZ_ASSERT(sDestroyedControllers.find(mLayersId) == sDestroyedControllers.end());
sDestroyedControllers[mLayersId] = this;
Unused << SendDestroy();
}
}
} // namespace layers

View File

@ -33,12 +33,10 @@ class RemoteContentController : public GeckoContentController
using GeckoContentController::APZStateChange;
public:
explicit RemoteContentController(uint64_t aLayersId,
dom::TabParent* aBrowserParent);
explicit RemoteContentController(uint64_t aLayersId);
virtual ~RemoteContentController();
// Needs to be called on the main thread.
virtual void RequestContentRepaint(const FrameMetrics& aFrameMetrics) override;
virtual void HandleTap(TapType aTapType,
@ -49,6 +47,10 @@ public:
virtual void PostDelayedTask(already_AddRefed<Runnable> aTask, int aDelayMs) override;
virtual bool IsRepaintThread() override;
virtual void DispatchToRepaintThread(already_AddRefed<Runnable> aTask) override;
virtual bool GetTouchSensitiveRegion(CSSRect* aOutRegion) override;
virtual void NotifyAPZStateChange(const ScrollableLayerGuid& aGuid,
@ -58,7 +60,6 @@ public:
virtual void NotifyMozMouseScrollEvent(const FrameMetrics::ViewID& aScrollId,
const nsString& aEvent) override;
// Needs to be called on the main thread.
virtual void NotifyFlushComplete() override;
virtual bool RecvUpdateHitRegion(const nsRegion& aRegion) override;
@ -68,15 +69,9 @@ public:
virtual void Destroy() override;
private:
bool CanSend()
{
MOZ_ASSERT(NS_IsMainThread());
return !!mBrowserParent;
}
MessageLoop* mUILoop;
MessageLoop* mCompositorThread;
uint64_t mLayersId;
RefPtr<dom::TabParent> mBrowserParent;
bool mCanSend;
// Mutex protecting members below accessed from multiple threads.
mozilla::Mutex mMutex;