Bug 930939 - Add a function to encapsulate running things on the APZ controller thread. r=botond a=bajaj
authorKartikaya Gupta <kgupta@mozilla.com>
Mon, 16 Feb 2015 14:39:27 -0500 (2015-02-16)
changeset 233042 7768b0596a5c432d52319700413005b540a63314
parent 233041 1046c97bfd7d984781d026cc3405416f29fda88a
child 233043 ee7bef814675ca52b0c6f03184ea860b08bd32c7
push id169
push userkgupta@mozilla.com
push dateMon, 16 Feb 2015 19:39:47 +0000 (2015-02-16)
treeherdermozilla-b2g37_v2_2@6b6fd89cd733 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersbotond, bajaj
bugs930939
milestone37.0a2
Bug 930939 - Add a function to encapsulate running things on the APZ controller thread. r=botond a=bajaj
gfx/layers/apz/util/APZThreadUtils.cpp
gfx/layers/apz/util/APZThreadUtils.h
layout/ipc/RenderFrameParent.cpp
--- a/gfx/layers/apz/util/APZThreadUtils.cpp
+++ b/gfx/layers/apz/util/APZThreadUtils.cpp
@@ -44,10 +44,28 @@ APZThreadUtils::AssertOnControllerThread
 /*static*/ void
 APZThreadUtils::AssertOnCompositorThread()
 {
   if (GetThreadAssertionsEnabled()) {
     Compositor::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();
+  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
+}
+
 } // namespace layers
 } // namespace mozilla
--- a/gfx/layers/apz/util/APZThreadUtils.h
+++ b/gfx/layers/apz/util/APZThreadUtils.h
@@ -1,16 +1,18 @@
 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
 /* 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_APZThreadUtils_h
 #define mozilla_layers_APZThreadUtils_h
 
+class Task;
+
 namespace mozilla {
 namespace layers {
 
 class APZThreadUtils
 {
 public:
   /**
    * In the gtest environment everything runs on one thread, so we
@@ -28,14 +30,21 @@ public:
   static void AssertOnControllerThread();
 
   /**
    * This can be used to assert that the current thread is the
    * compositor thread (which applies the async transform).
    * This does nothing if thread assertions are disabled.
    */
   static void AssertOnCompositorThread();
+
+  /**
+   * Run the given task on the APZ "controller thread" for this platform. If
+   * this function is called from the controller thread itself then the task is
+   * run immediately without getting queued.
+   */
+  static void RunOnControllerThread(Task* aTask);
 };
 
 } // namespace layers
 } // namespace mozilla
 
 #endif /* mozilla_layers_APZThreadUtils_h */
--- a/layout/ipc/RenderFrameParent.cpp
+++ b/layout/ipc/RenderFrameParent.cpp
@@ -11,16 +11,17 @@
 #include "gfxPrefs.h"
 #ifdef MOZ_ENABLE_D3D9_LAYER
 # include "LayerManagerD3D9.h"
 #endif //MOZ_ENABLE_D3D9_LAYER
 #include "mozilla/BrowserElementParent.h"
 #include "mozilla/dom/ContentChild.h"
 #include "mozilla/dom/TabParent.h"
 #include "mozilla/layers/APZCTreeManager.h"
+#include "mozilla/layers/APZThreadUtils.h"
 #include "mozilla/layers/CompositorParent.h"
 #include "mozilla/layers/LayerTransactionParent.h"
 #include "nsContentUtils.h"
 #include "nsFocusManager.h"
 #include "nsFrameLoader.h"
 #include "nsIObserver.h"
 #include "nsSubDocumentFrame.h"
 #include "nsView.h"
@@ -526,33 +527,40 @@ RenderFrameParent::ContentReceivedInputB
                                              bool aPreventDefault)
 {
   if (aGuid.mLayersId != mLayersId) {
     // Guard against bad data from hijacked child processes
     NS_ERROR("Unexpected layers id in ContentReceivedInputBlock; dropping message...");
     return;
   }
   if (GetApzcTreeManager()) {
-    GetApzcTreeManager()->ContentReceivedInputBlock(aInputBlockId, aPreventDefault);
+    APZThreadUtils::RunOnControllerThread(NewRunnableMethod(
+        GetApzcTreeManager(), &APZCTreeManager::ContentReceivedInputBlock,
+        aInputBlockId, aPreventDefault));
   }
 }
 
 void
 RenderFrameParent::SetTargetAPZC(uint64_t aInputBlockId,
                                  const nsTArray<ScrollableLayerGuid>& aTargets)
 {
   for (size_t i = 0; i < aTargets.Length(); i++) {
     if (aTargets[i].mLayersId != mLayersId) {
       // Guard against bad data from hijacked child processes
       NS_ERROR("Unexpected layers id in SetTargetAPZC; dropping message...");
       return;
     }
   }
   if (GetApzcTreeManager()) {
-    GetApzcTreeManager()->SetTargetAPZC(aInputBlockId, aTargets);
+    // need a local var to disambiguate between the SetTargetAPZC overloads.
+    void (APZCTreeManager::*setTargetApzcFunc)(uint64_t, const nsTArray<ScrollableLayerGuid>&)
+        = &APZCTreeManager::SetTargetAPZC;
+    APZThreadUtils::RunOnControllerThread(NewRunnableMethod(
+        GetApzcTreeManager(), setTargetApzcFunc,
+        aInputBlockId, aTargets));
   }
 }
 
 void
 RenderFrameParent::UpdateZoomConstraints(uint32_t aPresShellId,
                                          ViewID aViewId,
                                          bool aIsRoot,
                                          const ZoomConstraints& aConstraints)