Allow dispatching to the APZ controller thread from any thread. (bug 1147681 part 1, r=kats)

--HG--
extra : rebase_source : ce0beebda151fdf5adf69e998465c684b193db75
This commit is contained in:
David Anderson 2015-03-26 14:23:02 -07:00
parent 41292843b9
commit 274c9d4c17
6 changed files with 41 additions and 25 deletions

View File

@ -11,7 +11,7 @@ namespace mozilla {
namespace layers {
static bool sThreadAssertionsEnabled = true;
static PRThread* sControllerThread;
static MessageLoop* sControllerThread;
/*static*/ void
APZThreadUtils::SetThreadAssertionsEnabled(bool aEnabled) {
@ -23,22 +23,22 @@ APZThreadUtils::GetThreadAssertionsEnabled() {
return sThreadAssertionsEnabled;
}
/*static*/ void
APZThreadUtils::SetControllerThread(MessageLoop* aLoop)
{
// We must either be setting the initial controller thread, or removing it,
// or re-using an existing controller thread.
MOZ_ASSERT(!sControllerThread || !aLoop || sControllerThread == aLoop);
sControllerThread = aLoop;
}
/*static*/ void
APZThreadUtils::AssertOnControllerThread() {
if (!GetThreadAssertionsEnabled()) {
return;
}
static bool sControllerThreadDetermined = false;
if (!sControllerThreadDetermined) {
// Technically this may not actually pick up the correct controller thread,
// if the first call to this method happens from a non-controller thread.
// If the assertion below fires, it is possible that it is because
// sControllerThread is not actually the controller thread.
sControllerThread = PR_GetCurrentThread();
sControllerThreadDetermined = true;
}
MOZ_ASSERT(sControllerThread == PR_GetCurrentThread());
MOZ_ASSERT(sControllerThread == MessageLoop::current());
}
/*static*/ void
@ -52,25 +52,19 @@ APZThreadUtils::AssertOnCompositorThread()
/*static*/ void
APZThreadUtils::RunOnControllerThread(Task* aTask)
{
#ifdef MOZ_WIDGET_GONK
// On B2G the controller thread is the compositor thread, and this function
// is always called from the libui thread or the main thread.
MessageLoop* loop = CompositorParent::CompositorLoop();
if (!loop) {
if (!sControllerThread) {
// Could happen on startup
NS_WARNING("Dropping task posted to controller thread\n");
delete aTask;
return;
}
MOZ_ASSERT(MessageLoop::current() != loop);
loop->PostTask(FROM_HERE, aTask);
#else
// On non-B2G platforms this is only ever called from the controller thread
// itself.
AssertOnControllerThread();
aTask->Run();
delete aTask;
#endif
if (sControllerThread == MessageLoop::current()) {
aTask->Run();
delete aTask;
} else {
sControllerThread->PostTask(FROM_HERE, aTask);
}
}
} // namespace layers

View File

@ -22,6 +22,11 @@ public:
static void SetThreadAssertionsEnabled(bool aEnabled);
static bool GetThreadAssertionsEnabled();
/**
* Set the controller thread.
*/
static void SetControllerThread(MessageLoop* aLoop);
/**
* This can be used to assert that the current thread is the
* controller/UI thread (on which input events are received).

View File

@ -227,6 +227,12 @@ nsWindow::DoDraw(void)
}
}
void
nsWindow::ConfigureAPZControllerThread()
{
APZThreadUtils::SetControllerThread(CompositorParent::CompositorLoop());
}
/*static*/ nsEventStatus
nsWindow::DispatchInputEvent(WidgetGUIEvent& aEvent)
{

View File

@ -132,6 +132,8 @@ public:
virtual Composer2D* GetComposer2D() override;
void ConfigureAPZControllerThread() override;
protected:
nsWindow* mParent;
bool mVisible;

View File

@ -978,6 +978,8 @@ void nsBaseWidget::ConfigureAPZCTreeManager()
mAPZC = CompositorParent::GetAPZCTreeManager(rootLayerTreeId);
MOZ_ASSERT(mAPZC);
ConfigureAPZControllerThread();
mAPZC->SetDPI(GetDPI());
mAPZEventState = new APZEventState(this,
new ChromeProcessContentReceivedInputBlockCallback(mAPZC));
@ -990,6 +992,12 @@ void nsBaseWidget::ConfigureAPZCTreeManager()
}
}
void nsBaseWidget::ConfigureAPZControllerThread()
{
// By default the controller thread is the main thread.
APZThreadUtils::SetControllerThread(MessageLoop::current());
}
nsEventStatus
nsBaseWidget::ProcessUntransformedAPZEvent(WidgetInputEvent* aEvent,
const ScrollableLayerGuid& aGuid,

View File

@ -331,6 +331,7 @@ protected:
nsWidgetInitData *aInitData);
virtual void ConfigureAPZCTreeManager();
virtual void ConfigureAPZControllerThread();
virtual already_AddRefed<GeckoContentController> CreateRootContentController();
// Dispatch an event that has already been routed through APZ.