VsyncDispatcher.h 3.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104
  1. /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
  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 file,
  4. * You can obtain one at http://mozilla.org/MPL/2.0/. */
  5. #ifndef mozilla_widget_VsyncDispatcher_h
  6. #define mozilla_widget_VsyncDispatcher_h
  7. #include "mozilla/Mutex.h"
  8. #include "mozilla/TimeStamp.h"
  9. #include "nsISupportsImpl.h"
  10. #include "nsTArray.h"
  11. #include "mozilla/RefPtr.h"
  12. namespace mozilla {
  13. class VsyncObserver
  14. {
  15. NS_INLINE_DECL_THREADSAFE_REFCOUNTING(VsyncObserver)
  16. public:
  17. // The method called when a vsync occurs. Return true if some work was done.
  18. // In general, this vsync notification will occur on the hardware vsync
  19. // thread from VsyncSource. But it might also be called on PVsync ipc thread
  20. // if this notification is cross process. Thus all observer should check the
  21. // thread model before handling the real task.
  22. virtual bool NotifyVsync(TimeStamp aVsyncTimestamp) = 0;
  23. protected:
  24. VsyncObserver() {}
  25. virtual ~VsyncObserver() {}
  26. }; // VsyncObserver
  27. // Used to dispatch vsync events in the parent process to compositors.
  28. //
  29. // When the compositor is in-process, CompositorWidgets own a
  30. // CompositorVsyncDispatcher, and directly attach the compositor's observer
  31. // to it.
  32. //
  33. // When the compositor is out-of-process, the CompositorWidgetDelegate owns
  34. // the vsync dispatcher instead. The widget receives vsync observer/unobserve
  35. // commands via IPDL, and uses this to attach a CompositorWidgetVsyncObserver.
  36. // This observer forwards vsync notifications (on the vsync thread) to a
  37. // dedicated vsync I/O thread, which then forwards the notification to the
  38. // compositor thread in the compositor process.
  39. class CompositorVsyncDispatcher final
  40. {
  41. NS_INLINE_DECL_THREADSAFE_REFCOUNTING(CompositorVsyncDispatcher)
  42. public:
  43. CompositorVsyncDispatcher();
  44. // Called on the vsync thread when a hardware vsync occurs
  45. void NotifyVsync(TimeStamp aVsyncTimestamp);
  46. // Compositor vsync observers must be added/removed on the compositor thread
  47. void SetCompositorVsyncObserver(VsyncObserver* aVsyncObserver);
  48. void Shutdown();
  49. private:
  50. virtual ~CompositorVsyncDispatcher();
  51. void ObserveVsync(bool aEnable);
  52. Mutex mCompositorObserverLock;
  53. RefPtr<VsyncObserver> mCompositorVsyncObserver;
  54. bool mDidShutdown;
  55. };
  56. // Dispatch vsync event to ipc actor parent and chrome RefreshTimer.
  57. class RefreshTimerVsyncDispatcher final
  58. {
  59. NS_INLINE_DECL_THREADSAFE_REFCOUNTING(RefreshTimerVsyncDispatcher)
  60. public:
  61. RefreshTimerVsyncDispatcher();
  62. // Please check CompositorVsyncDispatcher::NotifyVsync().
  63. void NotifyVsync(TimeStamp aVsyncTimestamp);
  64. // Set chrome process's RefreshTimer to this dispatcher.
  65. // This function can be called from any thread.
  66. void SetParentRefreshTimer(VsyncObserver* aVsyncObserver);
  67. // Add or remove the content process' RefreshTimer to this dispatcher. This
  68. // will be a no-op for AddChildRefreshTimer() if the observer is already
  69. // registered.
  70. // These functions can be called from any thread.
  71. void AddChildRefreshTimer(VsyncObserver* aVsyncObserver);
  72. void RemoveChildRefreshTimer(VsyncObserver* aVsyncObserver);
  73. private:
  74. virtual ~RefreshTimerVsyncDispatcher();
  75. void UpdateVsyncStatus();
  76. bool NeedsVsync();
  77. Mutex mRefreshTimersLock;
  78. RefPtr<VsyncObserver> mParentRefreshTimer;
  79. nsTArray<RefPtr<VsyncObserver>> mChildRefreshTimers;
  80. };
  81. } // namespace mozilla
  82. #endif // mozilla_widget_VsyncDispatcher_h