VsyncBridgeChild.cpp 3.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156
  1. /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
  2. /* This Source Code Form is subject to the terms of the Mozilla Public
  3. * License, v. 2.0. If a copy of the MPL was not distributed with this
  4. * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
  5. #include "VsyncBridgeChild.h"
  6. #include "VsyncIOThreadHolder.h"
  7. #include "mozilla/dom/ContentChild.h"
  8. #include "GPUProcessManager.h"
  9. namespace mozilla {
  10. namespace gfx {
  11. VsyncBridgeChild::VsyncBridgeChild(RefPtr<VsyncIOThreadHolder> aThread, const uint64_t& aProcessToken)
  12. : mThread(aThread),
  13. mLoop(nullptr),
  14. mProcessToken(aProcessToken)
  15. {
  16. }
  17. VsyncBridgeChild::~VsyncBridgeChild()
  18. {
  19. }
  20. /* static */ RefPtr<VsyncBridgeChild>
  21. VsyncBridgeChild::Create(RefPtr<VsyncIOThreadHolder> aThread,
  22. const uint64_t& aProcessToken,
  23. Endpoint<PVsyncBridgeChild>&& aEndpoint)
  24. {
  25. RefPtr<VsyncBridgeChild> child = new VsyncBridgeChild(aThread, aProcessToken);
  26. RefPtr<nsIRunnable> task = NewRunnableMethod<Endpoint<PVsyncBridgeChild>&&>(
  27. child, &VsyncBridgeChild::Open, Move(aEndpoint));
  28. aThread->GetThread()->Dispatch(task.forget(), nsIThread::DISPATCH_NORMAL);
  29. return child;
  30. }
  31. void
  32. VsyncBridgeChild::Open(Endpoint<PVsyncBridgeChild>&& aEndpoint)
  33. {
  34. if (!aEndpoint.Bind(this)) {
  35. // The GPU Process Manager might be gone if we receive ActorDestroy very
  36. // late in shutdown.
  37. if (GPUProcessManager* gpm = GPUProcessManager::Get())
  38. gpm->NotifyRemoteActorDestroyed(mProcessToken);
  39. return;
  40. }
  41. mLoop = MessageLoop::current();
  42. // Last reference is freed in DeallocPVsyncBridgeChild.
  43. AddRef();
  44. }
  45. class NotifyVsyncTask : public Runnable
  46. {
  47. public:
  48. NotifyVsyncTask(RefPtr<VsyncBridgeChild> aVsyncBridge,
  49. TimeStamp aTimeStamp,
  50. const uint64_t& aLayersId)
  51. : mVsyncBridge(aVsyncBridge),
  52. mTimeStamp(aTimeStamp),
  53. mLayersId(aLayersId)
  54. {}
  55. NS_IMETHOD Run() override {
  56. mVsyncBridge->NotifyVsyncImpl(mTimeStamp, mLayersId);
  57. return NS_OK;
  58. }
  59. private:
  60. RefPtr<VsyncBridgeChild> mVsyncBridge;
  61. TimeStamp mTimeStamp;
  62. uint64_t mLayersId;
  63. };
  64. bool
  65. VsyncBridgeChild::IsOnVsyncIOThread() const
  66. {
  67. return MessageLoop::current() == mLoop;
  68. }
  69. void
  70. VsyncBridgeChild::NotifyVsync(TimeStamp aTimeStamp, const uint64_t& aLayersId)
  71. {
  72. // This should be on the Vsync thread (not the Vsync I/O thread).
  73. MOZ_ASSERT(!IsOnVsyncIOThread());
  74. RefPtr<NotifyVsyncTask> task = new NotifyVsyncTask(this, aTimeStamp, aLayersId);
  75. mLoop->PostTask(task.forget());
  76. }
  77. void
  78. VsyncBridgeChild::NotifyVsyncImpl(TimeStamp aTimeStamp, const uint64_t& aLayersId)
  79. {
  80. // This should be on the Vsync I/O thread.
  81. MOZ_ASSERT(IsOnVsyncIOThread());
  82. if (!mProcessToken) {
  83. return;
  84. }
  85. SendNotifyVsync(aTimeStamp, aLayersId);
  86. }
  87. void
  88. VsyncBridgeChild::Close()
  89. {
  90. if (!IsOnVsyncIOThread()) {
  91. mLoop->PostTask(NewRunnableMethod(this, &VsyncBridgeChild::Close));
  92. return;
  93. }
  94. // We clear mProcessToken when the channel is closed.
  95. if (!mProcessToken) {
  96. return;
  97. }
  98. // Clear the process token so we don't notify the GPUProcessManager. It already
  99. // knows we're closed since it manually called Close, and in fact the GPM could
  100. // have already been destroyed during shutdown.
  101. mProcessToken = 0;
  102. // Close the underlying IPC channel.
  103. PVsyncBridgeChild::Close();
  104. }
  105. void
  106. VsyncBridgeChild::ActorDestroy(ActorDestroyReason aWhy)
  107. {
  108. if (mProcessToken) {
  109. GPUProcessManager::Get()->NotifyRemoteActorDestroyed(mProcessToken);
  110. mProcessToken = 0;
  111. }
  112. }
  113. void
  114. VsyncBridgeChild::DeallocPVsyncBridgeChild()
  115. {
  116. Release();
  117. }
  118. void
  119. VsyncBridgeChild::ProcessingError(Result aCode, const char* aReason)
  120. {
  121. MOZ_RELEASE_ASSERT(aCode == MsgDropped, "Processing error in VsyncBridgeChild");
  122. }
  123. void
  124. VsyncBridgeChild::HandleFatalError(const char* aName, const char* aMsg) const
  125. {
  126. dom::ContentChild::FatalErrorIfNotUsingGPUProcess(aName, aMsg, OtherPid());
  127. }
  128. } // namespace gfx
  129. } // namespace mozilla