dom/ipc/VsyncChild.h
author Robert Mader <robert.mader@posteo.de>
Thu, 26 Nov 2020 19:15:04 +0000
changeset 558520 3a9dce7353402f5fc6cb2edf894822396417eea4
parent 558437 layout/ipc/VsyncChild.h@f35224f56cd5c742d78151e93954a797444cdfa5
permissions -rw-r--r--
Bug 1645528 - Connect nsRefreshDrivers in content processes with a widget-local vsync source r=mattwoodrow,emilio To allow `requestAnimationFrame()` and similar things to run at monitor speed if there is only a window-specific vsyncsource available. This is the case for Wayland and, in the future, EGL/X11. Other backends may opt for window specific vsyncsources as well at some point. The idea is to, instead of using global vsync objects, expose a vsyncsource from nsWindow and use it for refresh drivers. For the content process, move VsyncChild to BrowserChild, so for each Browserchild there is only one VsyncChild to which all refresh drivers connect. IPC in managed either by PBrowser or PBackground. Right now, PBrowser is only used on Wayland, as both PBrowser and the Wayland vsyncsource run on the main thread. Other backends keep using the background thread for now. While at it, make it so that we constantly update the refresh rate. This is necessary for Wayland, but also on other platforms variable refresh rates are increasingly common. When using PVsync, limit updates to once in every 250ms in order to minimize overhead while still updating fast. How to test: - run the Wayland backend - enable `widget.wayland_vsync.enabled` - optionally: disable `privacy.reduceTimerPrecision` - run `vsynctester.com` or `testufo.com` Expected results: Instead of fixed 60Hz, things should update at monitor refresh rate - e.g. 144Hz Original patch by Kenny Levinsen. Differential Revision: https://phabricator.services.mozilla.com/D93173

/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
/* 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_dom_ipc_VsyncChild_h
#define mozilla_dom_ipc_VsyncChild_h

#include "mozilla/dom/PVsyncChild.h"
#include "mozilla/RefPtr.h"
#include "nsISupportsImpl.h"
#include "nsTObserverArray.h"

namespace mozilla {

class VsyncObserver;

namespace dom {

// The PVsyncChild actor receives a vsync event from the main process and
// delivers it to the child process. Currently this is restricted to the main
// thread only. The actor will stay alive until the process dies or its
// PVsyncParent actor dies.
class VsyncChild final : public PVsyncChild {
  NS_INLINE_DECL_REFCOUNTING(VsyncChild)

  friend class PVsyncChild;

 public:
  VsyncChild();

  void AddChildRefreshTimer(VsyncObserver* aVsyncObserver);
  void RemoveChildRefreshTimer(VsyncObserver* aVsyncObserver);

  TimeDuration GetVsyncRate();

 private:
  virtual ~VsyncChild();

  mozilla::ipc::IPCResult RecvNotify(const VsyncEvent& aVsync);
  mozilla::ipc::IPCResult RecvVsyncRate(const float& aVsyncRate);
  virtual void ActorDestroy(ActorDestroyReason aActorDestroyReason) override;

  bool mIsShutdown;
  TimeDuration mVsyncRate;
  TimeStamp lastVsyncRateTime;
  nsTObserverArray<VsyncObserver*> mObservers;
};

}  // namespace dom
}  // namespace mozilla

#endif  // mozilla_dom_ipc_VsyncChild_h