gecko-dev/dom/ipc/VsyncParent.cpp

Ignoring revisions in .git-blame-ignore-revs. Click here to bypass and see the normal blame view.

108 строки
3.2 KiB
C++
Исходник Обычный вид История

/* -*- 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/. */
#include "VsyncParent.h"
#include "BackgroundParent.h"
#include "BackgroundParentImpl.h"
#include "gfxPlatform.h"
#include "mozilla/Unused.h"
#include "nsThreadUtils.h"
#include "VsyncSource.h"
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. Do that by transimitting the vsync rate `SendNotify()`. 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. Depends on D98254 Differential Revision: https://phabricator.services.mozilla.com/D93173
2020-12-02 12:47:53 +03:00
namespace mozilla::dom {
VsyncParent::VsyncParent()
: mObservingVsync(false),
mDestroyed(false),
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. Do that by transimitting the vsync rate `SendNotify()`. 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. Depends on D98254 Differential Revision: https://phabricator.services.mozilla.com/D93173
2020-12-02 12:47:53 +03:00
mInitialThread(NS_GetCurrentThread()) {}
2020-11-29 22:13:40 +03:00
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. Do that by transimitting the vsync rate `SendNotify()`. 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. Depends on D98254 Differential Revision: https://phabricator.services.mozilla.com/D93173
2020-12-02 12:47:53 +03:00
void VsyncParent::UpdateVsyncSource(
const RefPtr<gfx::VsyncSource>& aVsyncSource) {
mVsyncSource = aVsyncSource;
if (!mVsyncSource) {
mVsyncSource = gfxPlatform::GetPlatform()->GetHardwareVsync();
}
if (mObservingVsync && mVsyncDispatcher) {
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. Do that by transimitting the vsync rate `SendNotify()`. 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. Depends on D98254 Differential Revision: https://phabricator.services.mozilla.com/D93173
2020-12-02 12:47:53 +03:00
mVsyncDispatcher->RemoveChildRefreshTimer(this);
}
mVsyncDispatcher = mVsyncSource->GetRefreshTimerVsyncDispatcher();
if (mObservingVsync) {
mVsyncDispatcher->AddChildRefreshTimer(this);
}
}
bool VsyncParent::NotifyVsync(const VsyncEvent& aVsync) {
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. Do that by transimitting the vsync rate `SendNotify()`. 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. Depends on D98254 Differential Revision: https://phabricator.services.mozilla.com/D93173
2020-12-02 12:47:53 +03:00
if (IsOnInitialThread()) {
DispatchVsyncEvent(aVsync);
return true;
}
// Called on hardware vsync thread. We should post to current ipc thread.
nsCOMPtr<nsIRunnable> vsyncEvent = NewRunnableMethod<VsyncEvent>(
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. Do that by transimitting the vsync rate `SendNotify()`. 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. Depends on D98254 Differential Revision: https://phabricator.services.mozilla.com/D93173
2020-12-02 12:47:53 +03:00
"dom::VsyncParent::DispatchVsyncEvent", this,
&VsyncParent::DispatchVsyncEvent, aVsync);
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. Do that by transimitting the vsync rate `SendNotify()`. 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. Depends on D98254 Differential Revision: https://phabricator.services.mozilla.com/D93173
2020-12-02 12:47:53 +03:00
MOZ_ALWAYS_SUCCEEDS(mInitialThread->Dispatch(vsyncEvent, NS_DISPATCH_NORMAL));
return true;
}
void VsyncParent::DispatchVsyncEvent(const VsyncEvent& aVsync) {
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. Do that by transimitting the vsync rate `SendNotify()`. 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. Depends on D98254 Differential Revision: https://phabricator.services.mozilla.com/D93173
2020-12-02 12:47:53 +03:00
AssertIsOnInitialThread();
// If we call NotifyVsync() when we handle ActorDestroy() message, we might
// still call DispatchVsyncEvent().
// Similarly, we might also receive RecvUnobserveVsync() when call
// NotifyVsync(). We use mObservingVsync and mDestroyed flags to skip this
// notification.
if (mObservingVsync && !mDestroyed) {
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. Do that by transimitting the vsync rate `SendNotify()`. 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. Depends on D98254 Differential Revision: https://phabricator.services.mozilla.com/D93173
2020-12-02 12:47:53 +03:00
TimeDuration vsyncRate = mVsyncSource->GetGlobalDisplay().GetVsyncRate();
Unused << SendNotify(aVsync, vsyncRate.ToMilliseconds());
}
}
mozilla::ipc::IPCResult VsyncParent::RecvObserve() {
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. Do that by transimitting the vsync rate `SendNotify()`. 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. Depends on D98254 Differential Revision: https://phabricator.services.mozilla.com/D93173
2020-12-02 12:47:53 +03:00
AssertIsOnInitialThread();
if (!mObservingVsync) {
if (mVsyncDispatcher) {
mVsyncDispatcher->AddChildRefreshTimer(this);
}
mObservingVsync = true;
return IPC_OK();
}
return IPC_FAIL_NO_REASON(this);
}
mozilla::ipc::IPCResult VsyncParent::RecvUnobserve() {
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. Do that by transimitting the vsync rate `SendNotify()`. 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. Depends on D98254 Differential Revision: https://phabricator.services.mozilla.com/D93173
2020-12-02 12:47:53 +03:00
AssertIsOnInitialThread();
if (mObservingVsync) {
if (mVsyncDispatcher) {
mVsyncDispatcher->RemoveChildRefreshTimer(this);
}
mObservingVsync = false;
return IPC_OK();
}
return IPC_FAIL_NO_REASON(this);
}
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. Do that by transimitting the vsync rate `SendNotify()`. 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. Depends on D98254 Differential Revision: https://phabricator.services.mozilla.com/D93173
2020-12-02 12:47:53 +03:00
void VsyncParent::ActorDestroy(ActorDestroyReason aActorDestroyReason) {
MOZ_ASSERT(!mDestroyed);
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. Do that by transimitting the vsync rate `SendNotify()`. 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. Depends on D98254 Differential Revision: https://phabricator.services.mozilla.com/D93173
2020-12-02 12:47:53 +03:00
AssertIsOnInitialThread();
if (mObservingVsync && mVsyncDispatcher) {
mVsyncDispatcher->RemoveChildRefreshTimer(this);
}
mVsyncDispatcher = nullptr;
mDestroyed = true;
}
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. Do that by transimitting the vsync rate `SendNotify()`. 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. Depends on D98254 Differential Revision: https://phabricator.services.mozilla.com/D93173
2020-12-02 12:47:53 +03:00
bool VsyncParent::IsOnInitialThread() {
return NS_GetCurrentThread() == mInitialThread;
}
void VsyncParent::AssertIsOnInitialThread() { MOZ_ASSERT(IsOnInitialThread()); }
} // namespace mozilla::dom