mirror of
https://github.com/mozilla/gecko-dev.git
synced 2025-02-26 12:20:56 +00:00
Bug 1738971 - Part 4. Add VsyncWorkerChild to get vsync events. r=gfx-reviewers,dom-worker-reviewers,jgilbert,smaug
requestAnimationFrame callbacks are supposed to be synchronized with the vsync events into the refresh driver for the window. This patch adds an IPDL actor implementation for workers to subscribe as necessary to vsync events. Differential Revision: https://phabricator.services.mozilla.com/D130265
This commit is contained in:
parent
c439ab6cd3
commit
ddca5b5abd
67
dom/ipc/VsyncWorkerChild.cpp
Normal file
67
dom/ipc/VsyncWorkerChild.cpp
Normal file
@ -0,0 +1,67 @@
|
||||
/* -*- 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 "VsyncWorkerChild.h"
|
||||
#include "mozilla/dom/WorkerPrivate.h"
|
||||
#include "mozilla/dom/WorkerRef.h"
|
||||
#include "mozilla/dom/WorkerScope.h"
|
||||
|
||||
namespace mozilla::dom {
|
||||
|
||||
VsyncWorkerChild::VsyncWorkerChild() = default;
|
||||
|
||||
VsyncWorkerChild::~VsyncWorkerChild() = default;
|
||||
|
||||
bool VsyncWorkerChild::Initialize(WorkerPrivate* aWorkerPrivate) {
|
||||
MOZ_ASSERT(aWorkerPrivate);
|
||||
MOZ_ASSERT(!mWorkerRef);
|
||||
|
||||
mWorkerRef =
|
||||
IPCWorkerRef::Create(aWorkerPrivate, "VsyncWorkerChild",
|
||||
[self = RefPtr{this}]() { self->Destroy(); });
|
||||
return !!mWorkerRef;
|
||||
}
|
||||
|
||||
void VsyncWorkerChild::Destroy() {
|
||||
MOZ_ASSERT_IF(!CanSend(), !mWorkerRef);
|
||||
MOZ_ASSERT_IF(!CanSend(), !mObserving);
|
||||
Send__delete__(this);
|
||||
MOZ_ASSERT(!mWorkerRef);
|
||||
MOZ_ASSERT(!mObserving);
|
||||
}
|
||||
|
||||
void VsyncWorkerChild::TryObserve() {
|
||||
if (CanSend() && !mObserving) {
|
||||
mObserving = SendObserve();
|
||||
}
|
||||
}
|
||||
|
||||
void VsyncWorkerChild::TryUnobserve() {
|
||||
if (CanSend() && mObserving) {
|
||||
mObserving = !SendUnobserve();
|
||||
}
|
||||
}
|
||||
|
||||
mozilla::ipc::IPCResult VsyncWorkerChild::RecvNotify(const VsyncEvent& aVsync,
|
||||
const float& aVsyncRate) {
|
||||
// For MOZ_CAN_RUN_SCRIPT_BOUNDARY purposes: We know IPDL is explicitly
|
||||
// keeping our actor alive until it is done processing the messages. We know
|
||||
// that the WorkerGlobalScope callee is responsible keeping itself alive
|
||||
// during the OnVsync callback.
|
||||
WorkerPrivate* workerPrivate = mWorkerRef->Private();
|
||||
WorkerGlobalScope* scope = workerPrivate->GlobalScope();
|
||||
if (scope) {
|
||||
scope->OnVsync(aVsync);
|
||||
}
|
||||
return IPC_OK();
|
||||
}
|
||||
|
||||
void VsyncWorkerChild::ActorDestroy(ActorDestroyReason aActorDestroyReason) {
|
||||
mWorkerRef = nullptr;
|
||||
mObserving = false;
|
||||
}
|
||||
|
||||
} // namespace mozilla::dom
|
52
dom/ipc/VsyncWorkerChild.h
Normal file
52
dom/ipc/VsyncWorkerChild.h
Normal file
@ -0,0 +1,52 @@
|
||||
/* -*- 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_VsyncWorkerChild_h
|
||||
#define mozilla_dom_ipc_VsyncWorkerChild_h
|
||||
|
||||
#include "mozilla/dom/VsyncChild.h"
|
||||
#include "mozilla/RefPtr.h"
|
||||
#include "nsISupportsImpl.h"
|
||||
|
||||
namespace mozilla::dom {
|
||||
class DedicatedWorkerGlobalScope;
|
||||
class IPCWorkerRef;
|
||||
class WorkerPrivate;
|
||||
|
||||
// The PVsyncWorkerChild actor receives a vsync event from the main process and
|
||||
// delivers it to the child process. This is specific for workers which wish to
|
||||
// subscribe to vsync events to drive requestAnimationFrame callbacks.
|
||||
class VsyncWorkerChild final : public VsyncChild {
|
||||
NS_INLINE_DECL_REFCOUNTING(VsyncWorkerChild, override)
|
||||
|
||||
friend class PVsyncChild;
|
||||
|
||||
public:
|
||||
VsyncWorkerChild();
|
||||
|
||||
bool Initialize(WorkerPrivate* aWorkerPrivate);
|
||||
|
||||
void Destroy();
|
||||
|
||||
void TryObserve();
|
||||
|
||||
void TryUnobserve();
|
||||
|
||||
private:
|
||||
~VsyncWorkerChild() override;
|
||||
|
||||
mozilla::ipc::IPCResult RecvNotify(const VsyncEvent& aVsync,
|
||||
const float& aVsyncRate) override;
|
||||
|
||||
void ActorDestroy(ActorDestroyReason aActorDestroyReason) override;
|
||||
|
||||
RefPtr<IPCWorkerRef> mWorkerRef;
|
||||
bool mObserving = false;
|
||||
};
|
||||
|
||||
} // namespace mozilla::dom
|
||||
|
||||
#endif // mozilla_dom_ipc_VsyncWorkerChild_h
|
@ -81,6 +81,7 @@ EXPORTS.mozilla.dom += [
|
||||
"VsyncChild.h",
|
||||
"VsyncMainChild.h",
|
||||
"VsyncParent.h",
|
||||
"VsyncWorkerChild.h",
|
||||
"WindowGlobalActor.h",
|
||||
"WindowGlobalChild.h",
|
||||
"WindowGlobalParent.h",
|
||||
@ -145,6 +146,7 @@ SOURCES += [
|
||||
"ProcessHangMonitor.cpp",
|
||||
"VsyncMainChild.cpp",
|
||||
"VsyncParent.cpp",
|
||||
"VsyncWorkerChild.cpp",
|
||||
]
|
||||
|
||||
PREPROCESSED_IPDL_SOURCES += [
|
||||
|
@ -34,6 +34,7 @@ class nsISerialEventTarget;
|
||||
|
||||
namespace mozilla {
|
||||
class ErrorResult;
|
||||
struct VsyncEvent;
|
||||
|
||||
namespace extensions {
|
||||
|
||||
@ -303,6 +304,9 @@ class WorkerGlobalScope : public WorkerGlobalScopeBase,
|
||||
|
||||
virtual void OnDocumentVisible(bool aVisible) {}
|
||||
|
||||
MOZ_CAN_RUN_SCRIPT_BOUNDARY
|
||||
virtual void OnVsync(const VsyncEvent& aVsync) {}
|
||||
|
||||
protected:
|
||||
~WorkerGlobalScope();
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user