Bug 1091037 - Raise ImageBridge thread priority r=gsvelto,nical
authorSotaro Ikeda <sikeda@mozilla.com>
Thu, 07 May 2015 06:53:47 -0700
changeset 242829 d0b48a557161308bc7459afe0f7ce5fbcd8e51c5
parent 242828 ce6cfd9bad2fd2970b6470e22e68f5a6ac44f895
child 242830 ee863cf58138c1d0c5eecd19334ecf68fa1f5ad2
push id12802
push userkwierso@gmail.com
push dateThu, 07 May 2015 22:38:36 +0000
treeherderfx-team@b9d40b34df46 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersgsvelto, nical
bugs1091037
milestone40.0a1
Bug 1091037 - Raise ImageBridge thread priority r=gsvelto,nical
gfx/layers/ipc/ImageBridgeChild.cpp
gfx/layers/ipc/ImageBridgeChild.h
gfx/layers/ipc/ImageBridgeParent.cpp
gfx/layers/ipc/ImageBridgeParent.h
gfx/layers/ipc/PImageBridge.ipdl
hal/Hal.cpp
hal/Hal.h
hal/fallback/FallbackThreadPriority.cpp
hal/gonk/GonkHal.cpp
hal/sandbox/SandboxHal.cpp
--- a/gfx/layers/ipc/ImageBridgeChild.cpp
+++ b/gfx/layers/ipc/ImageBridgeChild.cpp
@@ -521,16 +521,29 @@ ImageBridgeChild::EndTransaction()
     }
     default:
       NS_RUNTIMEABORT("not reached");
     }
   }
   SendPendingAsyncMessges();
 }
 
+void
+ImageBridgeChild::SendImageBridgeThreadId()
+{
+#ifdef MOZ_WIDGET_GONK
+  SendImageBridgeThreadId(gettid());
+#endif
+}
+
+static void CallSendImageBridgeThreadId(ImageBridgeChild* aImageBridgeChild)
+{
+  MOZ_ASSERT(InImageBridgeChildThread());
+  aImageBridgeChild->SendImageBridgeThreadId();
+}
 
 PImageBridgeChild*
 ImageBridgeChild::StartUpInChildProcess(Transport* aTransport,
                                         ProcessId aOtherPid)
 {
   MOZ_ASSERT(NS_IsMainThread());
 
   gfxPlatform::GetPlatform();
@@ -540,16 +553,20 @@ ImageBridgeChild::StartUpInChildProcess(
     return nullptr;
   }
 
   sImageBridgeChildSingleton = new ImageBridgeChild();
   sImageBridgeChildSingleton->GetMessageLoop()->PostTask(
     FROM_HERE,
     NewRunnableFunction(ConnectImageBridgeInChildProcess,
                         aTransport, aOtherPid));
+  sImageBridgeChildSingleton->GetMessageLoop()->PostTask(
+    FROM_HERE,
+    NewRunnableFunction(CallSendImageBridgeThreadId,
+                        sImageBridgeChildSingleton.get()));
 
   return sImageBridgeChildSingleton;
 }
 
 void ImageBridgeChild::ShutDown()
 {
   MOZ_ASSERT(NS_IsMainThread());
   if (ImageBridgeChild::IsCreated()) {
@@ -593,16 +610,20 @@ bool ImageBridgeChild::StartUpOnThread(T
     sImageBridgeChildThread = aThread;
     if (!aThread->IsRunning()) {
       aThread->Start();
     }
     sImageBridgeChildSingleton = new ImageBridgeChild();
     sImageBridgeParentSingleton = new ImageBridgeParent(
       CompositorParent::CompositorLoop(), nullptr, base::GetCurrentProcId());
     sImageBridgeChildSingleton->ConnectAsync(sImageBridgeParentSingleton);
+    sImageBridgeChildSingleton->GetMessageLoop()->PostTask(
+      FROM_HERE,
+      NewRunnableFunction(CallSendImageBridgeThreadId,
+                          sImageBridgeChildSingleton.get()));
     return true;
   } else {
     return false;
   }
 }
 
 bool InImageBridgeChildThread()
 {
--- a/gfx/layers/ipc/ImageBridgeChild.h
+++ b/gfx/layers/ipc/ImageBridgeChild.h
@@ -147,16 +147,19 @@ public:
   static ImageBridgeChild* GetSingleton();
 
 
   /**
    * Dispatches a task to the ImageBridgeChild thread to do the connection
    */
   void ConnectAsync(ImageBridgeParent* aParent);
 
+  using PImageBridgeChild::SendImageBridgeThreadId;
+  void SendImageBridgeThreadId();
+
   static void IdentifyCompositorTextureHost(const TextureFactoryIdentifier& aIdentifier);
 
   void BeginTransaction();
   void EndTransaction();
 
   /**
    * Returns the ImageBridgeChild's thread.
    *
--- a/gfx/layers/ipc/ImageBridgeParent.cpp
+++ b/gfx/layers/ipc/ImageBridgeParent.cpp
@@ -7,16 +7,18 @@
 #include "ImageBridgeParent.h"
 #include <stdint.h>                     // for uint64_t, uint32_t
 #include "CompositableHost.h"           // for CompositableParent, Create
 #include "base/message_loop.h"          // for MessageLoop
 #include "base/process.h"               // for ProcessId
 #include "base/task.h"                  // for CancelableTask, DeleteTask, etc
 #include "base/tracked.h"               // for FROM_HERE
 #include "mozilla/gfx/Point.h"                   // for IntSize
+#include "mozilla/Hal.h"                // for hal::SetCurrentThreadPriority()
+#include "mozilla/HalTypes.h"           // for hal::THREAD_PRIORITY_COMPOSITOR
 #include "mozilla/ipc/MessageChannel.h" // for MessageChannel, etc
 #include "mozilla/ipc/ProtocolUtils.h"
 #include "mozilla/ipc/Transport.h"      // for Transport
 #include "mozilla/layers/CompositableTransactionParent.h"
 #include "mozilla/layers/CompositorParent.h"  // for CompositorParent
 #include "mozilla/layers/LayerManagerComposite.h"
 #include "mozilla/layers/LayersMessages.h"  // for EditReply
 #include "mozilla/layers/LayersSurfaces.h"  // for PGrallocBufferParent
@@ -48,16 +50,17 @@ MessageLoop* ImageBridgeParent::sMainLoo
 // defined in CompositorParent.cpp
 CompositorThreadHolder* GetCompositorThreadHolder();
 
 ImageBridgeParent::ImageBridgeParent(MessageLoop* aLoop,
                                      Transport* aTransport,
                                      ProcessId aChildProcessId)
   : mMessageLoop(aLoop)
   , mTransport(aTransport)
+  , mSetChildThreadPriority(false)
   , mCompositorThreadHolder(GetCompositorThreadHolder())
 {
   MOZ_ASSERT(NS_IsMainThread());
   sMainLoop = MessageLoop::current();
 
   // top-level actors must be destroyed on the main thread.
   SetMessageLoopToPostDestructionTo(sMainLoop);
 
@@ -90,16 +93,30 @@ ImageBridgeParent::GetCompositorBackendT
 void
 ImageBridgeParent::ActorDestroy(ActorDestroyReason aWhy)
 {
   MessageLoop::current()->PostTask(
     FROM_HERE,
     NewRunnableMethod(this, &ImageBridgeParent::DeferredDestroy));
 }
 
+bool
+ImageBridgeParent::RecvImageBridgeThreadId(const PlatformThreadId& aThreadId)
+{
+  MOZ_ASSERT(!mSetChildThreadPriority);
+  if (mSetChildThreadPriority) {
+    return false;
+  }
+  mSetChildThreadPriority = true;
+#ifdef MOZ_WIDGET_GONK
+  hal::SetThreadPriority(aThreadId, hal::THREAD_PRIORITY_COMPOSITOR);
+#endif
+  return true;
+}
+
 class MOZ_STACK_CLASS AutoImageBridgeParentAsyncMessageSender
 {
 public:
   explicit AutoImageBridgeParentAsyncMessageSender(ImageBridgeParent* aImageBridge)
     : mImageBridge(aImageBridge) {}
 
   ~AutoImageBridgeParentAsyncMessageSender()
   {
--- a/gfx/layers/ipc/ImageBridgeParent.h
+++ b/gfx/layers/ipc/ImageBridgeParent.h
@@ -62,16 +62,17 @@ public:
   virtual void SendAsyncMessage(const InfallibleTArray<AsyncParentMessageData>& aMessage) override;
 
   virtual base::ProcessId GetChildProcessId() override
   {
     return OtherPid();
   }
 
   // PImageBridge
+  virtual bool RecvImageBridgeThreadId(const PlatformThreadId& aThreadId) override;
   virtual bool RecvUpdate(EditArray&& aEdits, EditReplyArray* aReply) override;
   virtual bool RecvUpdateNoSwap(EditArray&& aEdits) override;
 
   virtual bool IsAsync() const override { return true; }
 
   PCompositableParent* AllocPCompositableParent(const TextureInfo& aInfo,
                                                 uint64_t*) override;
   bool DeallocPCompositableParent(PCompositableParent* aActor) override;
@@ -138,23 +139,24 @@ public:
   // Overriden from IToplevelProtocol
   IToplevelProtocol*
   CloneToplevel(const InfallibleTArray<ProtocolFdMapping>& aFds,
                 base::ProcessHandle aPeerProcess,
                 mozilla::ipc::ProtocolCloneContext* aCtx) override;
 
 private:
   void DeferredDestroy();
-
   MessageLoop* mMessageLoop;
   Transport* mTransport;
   // This keeps us alive until ActorDestroy(), at which point we do a
   // deferred destruction of ourselves.
   nsRefPtr<ImageBridgeParent> mSelfRef;
 
+  bool mSetChildThreadPriority;
+
   /**
    * Map of all living ImageBridgeParent instances
    */
   static std::map<base::ProcessId, ImageBridgeParent*> sImageBridges;
 
   static MessageLoop* sMainLoop;
 
   nsRefPtr<CompositorThreadHolder> mCompositorThreadHolder;
--- a/gfx/layers/ipc/PImageBridge.ipdl
+++ b/gfx/layers/ipc/PImageBridge.ipdl
@@ -10,16 +10,18 @@ include protocol PLayer;
 include protocol PTexture;
 include ProtocolTypes;
 
 include "mozilla/GfxMessageUtils.h";
 
 using struct mozilla::layers::TextureInfo from "mozilla/layers/CompositorTypes.h";
 using mozilla::layers::TextureFlags from "mozilla/layers/CompositorTypes.h";
 
+using PlatformThreadId from "base/platform_thread.h";
+
 namespace mozilla {
 namespace layers {
 
 /**
  * The PImageBridge protocol is used to allow isolated threads or processes to push
  * frames directly to the compositor thread/process without relying on the main thread
  * which might be too busy dealing with content script.
  */
@@ -28,16 +30,18 @@ sync protocol PImageBridge
   manages PCompositable;
   manages PTexture;
 
 child:
   async ParentAsyncMessages(AsyncParentMessageData[] aMessages);
 
 parent:
 
+  async ImageBridgeThreadId(PlatformThreadId aTreahdId);
+
   sync Update(CompositableOperation[] ops) returns (EditReply[] reply);
   async UpdateNoSwap(CompositableOperation[] ops);
 
   // First step of the destruction sequence. This puts ImageBridge
   // in a state in which it can't send asynchronous messages
   // so as to not race with the upcomming Stop message and destruction.
   // In the child side, the Stop message is not sent right after WillStop,
   // it is scheduled in the ImageBridgeChild's message queue in order to ensure
--- a/hal/Hal.cpp
+++ b/hal/Hal.cpp
@@ -859,16 +859,23 @@ SetProcessPriority(int aPid, ProcessPrio
 }
 
 void
 SetCurrentThreadPriority(hal::ThreadPriority aThreadPriority)
 {
   PROXY_IF_SANDBOXED(SetCurrentThreadPriority(aThreadPriority));
 }
 
+void
+SetThreadPriority(PlatformThreadId aThreadId,
+                  hal::ThreadPriority aThreadPriority)
+{
+  PROXY_IF_SANDBOXED(SetThreadPriority(aThreadId, aThreadPriority));
+}
+
 // From HalTypes.h.
 const char*
 ProcessPriorityToString(ProcessPriority aPriority)
 {
   switch (aPriority) {
   case PROCESS_PRIORITY_MASTER:
     return "MASTER";
   case PROCESS_PRIORITY_PREALLOC:
--- a/hal/Hal.h
+++ b/hal/Hal.h
@@ -5,16 +5,17 @@
  * You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #ifndef mozilla_Hal_h
 #define mozilla_Hal_h
 
 #include "mozilla/hal_sandbox/PHal.h"
 #include "mozilla/HalTypes.h"
 #include "base/basictypes.h"
+#include "base/platform_thread.h"
 #include "mozilla/Observer.h"
 #include "mozilla/Types.h"
 #include "nsTArray.h"
 #include "mozilla/dom/MozPowerManagerBinding.h"
 #include "mozilla/dom/battery/Types.h"
 #include "mozilla/dom/network/Types.h"
 #include "mozilla/dom/power/Types.h"
 #include "mozilla/dom/ScreenOrientation.h"
@@ -481,16 +482,24 @@ void SetProcessPriority(int aPid,
 /**
  * Set the current thread's priority to appropriate platform-specific value for
  * given functionality. Instead of providing arbitrary priority numbers you
  * must specify a type of function like THREAD_PRIORITY_COMPOSITOR.
  */
 void SetCurrentThreadPriority(hal::ThreadPriority aThreadPriority);
 
 /**
+ * Set a thread priority to appropriate platform-specific value for
+ * given functionality. Instead of providing arbitrary priority numbers you
+ * must specify a type of function like THREAD_PRIORITY_COMPOSITOR.
+ */
+void SetThreadPriority(PlatformThreadId aThreadId,
+                       hal::ThreadPriority aThreadPriority);
+
+/**
  * Register an observer for the FM radio.
  */
 void RegisterFMRadioObserver(hal::FMRadioObserver* aRadioObserver);
 
 /**
  * Unregister the observer for the FM radio.
  */
 void UnregisterFMRadioObserver(hal::FMRadioObserver* aRadioObserver);
--- a/hal/fallback/FallbackThreadPriority.cpp
+++ b/hal/fallback/FallbackThreadPriority.cpp
@@ -12,10 +12,18 @@ namespace hal_impl {
 
 void
 SetCurrentThreadPriority(ThreadPriority aPriority)
 {
   HAL_LOG("FallbackThreadPriority - SetCurrentThreadPriority(%d)\n",
           ThreadPriorityToString(aPriority));
 }
 
+void
+SetThreadPriority(PlatformThreadId aThreadId,
+                  ThreadPriority aPriority)
+{
+  HAL_LOG("FallbackThreadPriority - SetThreadPriority(%d, %d)\n",
+          aThreadId, ThreadPriorityToString(aPriority));
+}
+
 } // hal_impl
 } // namespace mozilla
--- a/hal/gonk/GonkHal.cpp
+++ b/hal/gonk/GonkHal.cpp
@@ -1909,17 +1909,17 @@ EnsureThreadPriorityPrefs(ThreadPriority
     Preferences::AddIntVarCache(&prefs->priorities[i].realTime,
                                 realTimeStr.get());
   }
 
   prefs->initialized = true;
 }
 
 static void
-SetThreadPriority(pid_t aTid, hal::ThreadPriority aThreadPriority)
+DoSetThreadPriority(pid_t aTid, hal::ThreadPriority aThreadPriority)
 {
   // See bug 999115, we can only read preferences on the main thread otherwise
   // we create a race condition in HAL
   MOZ_ASSERT(NS_IsMainThread(), "Can only set thread priorities on main thread");
   MOZ_ASSERT(aThreadPriority >= 0);
 
   static ThreadPriorityPrefs prefs = { 0 };
   EnsureThreadPriorityPrefs(&prefs);
@@ -1960,35 +1960,42 @@ public:
   SetThreadPriorityRunnable(pid_t aThreadId, hal::ThreadPriority aThreadPriority)
     : mThreadId(aThreadId)
     , mThreadPriority(aThreadPriority)
   { }
 
   NS_IMETHOD Run()
   {
     NS_ASSERTION(NS_IsMainThread(), "Can only set thread priorities on main thread");
-    hal_impl::SetThreadPriority(mThreadId, mThreadPriority);
+    hal_impl::DoSetThreadPriority(mThreadId, mThreadPriority);
     return NS_OK;
   }
 
 private:
   pid_t mThreadId;
   hal::ThreadPriority mThreadPriority;
 };
 
 } // anonymous namespace
 
 void
 SetCurrentThreadPriority(ThreadPriority aThreadPriority)
 {
+  pid_t threadId = gettid();
+  hal_impl::SetThreadPriority(threadId, aThreadPriority);
+}
+
+void
+SetThreadPriority(PlatformThreadId aThreadId,
+                         ThreadPriority aThreadPriority)
+{
   switch (aThreadPriority) {
     case THREAD_PRIORITY_COMPOSITOR: {
-      pid_t threadId = gettid();
       nsCOMPtr<nsIRunnable> runnable =
-        new SetThreadPriorityRunnable(threadId, aThreadPriority);
+        new SetThreadPriorityRunnable(aThreadId, aThreadPriority);
       NS_DispatchToMainThread(runnable);
       break;
     }
     default:
       HAL_LOG("Unrecognized thread priority %d; Doing nothing",
               aThreadPriority);
       return;
   }
--- a/hal/sandbox/SandboxHal.cpp
+++ b/hal/sandbox/SandboxHal.cpp
@@ -351,16 +351,23 @@ void
 SetProcessPriority(int aPid, ProcessPriority aPriority, uint32_t aLRU)
 {
   NS_RUNTIMEABORT("Only the main process may set processes' priorities.");
 }
 
 void
 SetCurrentThreadPriority(ThreadPriority aThreadPriority)
 {
+  NS_RUNTIMEABORT("Setting current thread priority cannot be called from sandboxed contexts.");
+}
+
+void
+SetThreadPriority(PlatformThreadId aThreadId,
+                  ThreadPriority aThreadPriority)
+{
   NS_RUNTIMEABORT("Setting thread priority cannot be called from sandboxed contexts.");
 }
 
 void
 EnableFMRadio(const hal::FMRadioSettings& aSettings)
 {
   NS_RUNTIMEABORT("FM radio cannot be called from sandboxed contexts.");
 }