2019-11-27 03:21:33 +03:00
|
|
|
/* -*- 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/. */
|
|
|
|
|
|
|
|
#ifdef MOZ_WAYLAND
|
|
|
|
|
|
|
|
# include "WaylandVsyncSource.h"
|
|
|
|
# include "nsThreadUtils.h"
|
|
|
|
# include "nsISupportsImpl.h"
|
|
|
|
# include "MainThreadUtils.h"
|
|
|
|
|
|
|
|
# include <gdk/gdkwayland.h>
|
|
|
|
|
2020-09-04 13:54:49 +03:00
|
|
|
using namespace mozilla::widget;
|
|
|
|
|
2019-11-27 03:21:33 +03:00
|
|
|
namespace mozilla {
|
|
|
|
|
Bug 1711244 - Integrate NativeLayerWayland with WaylandVsyncSource, r=stransky,gfx-reviewers,jrmuizel
Make the vsync source request frame callbacks from opaque native
layers. This is necessary as opaque layers may occlude the
MozContainer surface, which is normally used for frame callbacks.
Wayland compositors may (and are encouraged to) optimize away
such callbacks, so we need to make sure to request frame callbacks
from actually visible surfaces.
Callbacks are requested for all layers, but only the first callback
will trigger the vsync source.
In order to get this right concerning multiple requested callbacks,
possibly being called from different threads etc., introduce a
callback abstraction, `CallbackMultiplexHelper`, to make this simple
to handle for callers.
Differential Revision: https://phabricator.services.mozilla.com/D116026
2021-06-10 18:12:54 +03:00
|
|
|
static void WaylandVsyncSourceCallbackHandler(void* aData,
|
|
|
|
struct wl_callback* aCallback,
|
|
|
|
uint32_t aTime) {
|
2020-06-05 21:35:22 +03:00
|
|
|
WaylandVsyncSource::WaylandDisplay* context =
|
Bug 1711244 - Integrate NativeLayerWayland with WaylandVsyncSource, r=stransky,gfx-reviewers,jrmuizel
Make the vsync source request frame callbacks from opaque native
layers. This is necessary as opaque layers may occlude the
MozContainer surface, which is normally used for frame callbacks.
Wayland compositors may (and are encouraged to) optimize away
such callbacks, so we need to make sure to request frame callbacks
from actually visible surfaces.
Callbacks are requested for all layers, but only the first callback
will trigger the vsync source.
In order to get this right concerning multiple requested callbacks,
possibly being called from different threads etc., introduce a
callback abstraction, `CallbackMultiplexHelper`, to make this simple
to handle for callers.
Differential Revision: https://phabricator.services.mozilla.com/D116026
2021-06-10 18:12:54 +03:00
|
|
|
(WaylandVsyncSource::WaylandDisplay*)aData;
|
|
|
|
wl_callback_destroy(aCallback);
|
|
|
|
context->FrameCallback(aTime);
|
|
|
|
}
|
|
|
|
|
|
|
|
static void WaylandVsyncSourceCallbackHandler(void* aData, uint32_t aTime) {
|
|
|
|
WaylandVsyncSource::WaylandDisplay* context =
|
|
|
|
(WaylandVsyncSource::WaylandDisplay*)aData;
|
|
|
|
context->FrameCallback(aTime);
|
2019-11-27 03:21:33 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
static const struct wl_callback_listener WaylandVsyncSourceCallbackListener = {
|
|
|
|
WaylandVsyncSourceCallbackHandler};
|
|
|
|
|
Bug 1711244 - Integrate NativeLayerWayland with WaylandVsyncSource, r=stransky,gfx-reviewers,jrmuizel
Make the vsync source request frame callbacks from opaque native
layers. This is necessary as opaque layers may occlude the
MozContainer surface, which is normally used for frame callbacks.
Wayland compositors may (and are encouraged to) optimize away
such callbacks, so we need to make sure to request frame callbacks
from actually visible surfaces.
Callbacks are requested for all layers, but only the first callback
will trigger the vsync source.
In order to get this right concerning multiple requested callbacks,
possibly being called from different threads etc., introduce a
callback abstraction, `CallbackMultiplexHelper`, to make this simple
to handle for callers.
Differential Revision: https://phabricator.services.mozilla.com/D116026
2021-06-10 18:12:54 +03:00
|
|
|
WaylandVsyncSource::WaylandDisplay::WaylandDisplay()
|
|
|
|
: mMutex("WaylandVsyncSource"),
|
2020-11-03 14:38:35 +03:00
|
|
|
mIsShutdown(false),
|
2019-11-27 03:21:33 +03:00
|
|
|
mVsyncEnabled(false),
|
|
|
|
mMonitorEnabled(false),
|
Bug 1711244 - Integrate NativeLayerWayland with WaylandVsyncSource, r=stransky,gfx-reviewers,jrmuizel
Make the vsync source request frame callbacks from opaque native
layers. This is necessary as opaque layers may occlude the
MozContainer surface, which is normally used for frame callbacks.
Wayland compositors may (and are encouraged to) optimize away
such callbacks, so we need to make sure to request frame callbacks
from actually visible surfaces.
Callbacks are requested for all layers, but only the first callback
will trigger the vsync source.
In order to get this right concerning multiple requested callbacks,
possibly being called from different threads etc., introduce a
callback abstraction, `CallbackMultiplexHelper`, to make this simple
to handle for callers.
Differential Revision: https://phabricator.services.mozilla.com/D116026
2021-06-10 18:12:54 +03:00
|
|
|
mCallbackRequested(false),
|
|
|
|
mContainer(nullptr),
|
|
|
|
mVsyncRate(TimeDuration::FromMilliseconds(1000.0 / 60.0)),
|
2020-11-03 14:39:18 +03:00
|
|
|
mLastVsyncTimeStamp(TimeStamp::Now()) {
|
2019-11-27 03:21:33 +03:00
|
|
|
MOZ_ASSERT(NS_IsMainThread());
|
Bug 1711244 - Integrate NativeLayerWayland with WaylandVsyncSource, r=stransky,gfx-reviewers,jrmuizel
Make the vsync source request frame callbacks from opaque native
layers. This is necessary as opaque layers may occlude the
MozContainer surface, which is normally used for frame callbacks.
Wayland compositors may (and are encouraged to) optimize away
such callbacks, so we need to make sure to request frame callbacks
from actually visible surfaces.
Callbacks are requested for all layers, but only the first callback
will trigger the vsync source.
In order to get this right concerning multiple requested callbacks,
possibly being called from different threads etc., introduce a
callback abstraction, `CallbackMultiplexHelper`, to make this simple
to handle for callers.
Differential Revision: https://phabricator.services.mozilla.com/D116026
2021-06-10 18:12:54 +03:00
|
|
|
}
|
2019-11-27 03:21:33 +03:00
|
|
|
|
Bug 1711244 - Integrate NativeLayerWayland with WaylandVsyncSource, r=stransky,gfx-reviewers,jrmuizel
Make the vsync source request frame callbacks from opaque native
layers. This is necessary as opaque layers may occlude the
MozContainer surface, which is normally used for frame callbacks.
Wayland compositors may (and are encouraged to) optimize away
such callbacks, so we need to make sure to request frame callbacks
from actually visible surfaces.
Callbacks are requested for all layers, but only the first callback
will trigger the vsync source.
In order to get this right concerning multiple requested callbacks,
possibly being called from different threads etc., introduce a
callback abstraction, `CallbackMultiplexHelper`, to make this simple
to handle for callers.
Differential Revision: https://phabricator.services.mozilla.com/D116026
2021-06-10 18:12:54 +03:00
|
|
|
void WaylandVsyncSource::WaylandDisplay::MaybeUpdateSource(
|
|
|
|
MozContainer* aContainer) {
|
|
|
|
MutexAutoLock lock(mMutex);
|
|
|
|
|
|
|
|
if (aContainer == mContainer) {
|
|
|
|
return;
|
|
|
|
}
|
2020-11-03 14:39:18 +03:00
|
|
|
|
Bug 1711244 - Integrate NativeLayerWayland with WaylandVsyncSource, r=stransky,gfx-reviewers,jrmuizel
Make the vsync source request frame callbacks from opaque native
layers. This is necessary as opaque layers may occlude the
MozContainer surface, which is normally used for frame callbacks.
Wayland compositors may (and are encouraged to) optimize away
such callbacks, so we need to make sure to request frame callbacks
from actually visible surfaces.
Callbacks are requested for all layers, but only the first callback
will trigger the vsync source.
In order to get this right concerning multiple requested callbacks,
possibly being called from different threads etc., introduce a
callback abstraction, `CallbackMultiplexHelper`, to make this simple
to handle for callers.
Differential Revision: https://phabricator.services.mozilla.com/D116026
2021-06-10 18:12:54 +03:00
|
|
|
mNativeLayerRoot = nullptr;
|
|
|
|
mContainer = aContainer;
|
|
|
|
|
|
|
|
if (mMonitorEnabled) {
|
|
|
|
mCallbackRequested = false;
|
2021-09-08 03:04:09 +03:00
|
|
|
Refresh(lock);
|
Bug 1711244 - Integrate NativeLayerWayland with WaylandVsyncSource, r=stransky,gfx-reviewers,jrmuizel
Make the vsync source request frame callbacks from opaque native
layers. This is necessary as opaque layers may occlude the
MozContainer surface, which is normally used for frame callbacks.
Wayland compositors may (and are encouraged to) optimize away
such callbacks, so we need to make sure to request frame callbacks
from actually visible surfaces.
Callbacks are requested for all layers, but only the first callback
will trigger the vsync source.
In order to get this right concerning multiple requested callbacks,
possibly being called from different threads etc., introduce a
callback abstraction, `CallbackMultiplexHelper`, to make this simple
to handle for callers.
Differential Revision: https://phabricator.services.mozilla.com/D116026
2021-06-10 18:12:54 +03:00
|
|
|
}
|
2019-11-27 03:21:33 +03:00
|
|
|
}
|
|
|
|
|
Bug 1711244 - Integrate NativeLayerWayland with WaylandVsyncSource, r=stransky,gfx-reviewers,jrmuizel
Make the vsync source request frame callbacks from opaque native
layers. This is necessary as opaque layers may occlude the
MozContainer surface, which is normally used for frame callbacks.
Wayland compositors may (and are encouraged to) optimize away
such callbacks, so we need to make sure to request frame callbacks
from actually visible surfaces.
Callbacks are requested for all layers, but only the first callback
will trigger the vsync source.
In order to get this right concerning multiple requested callbacks,
possibly being called from different threads etc., introduce a
callback abstraction, `CallbackMultiplexHelper`, to make this simple
to handle for callers.
Differential Revision: https://phabricator.services.mozilla.com/D116026
2021-06-10 18:12:54 +03:00
|
|
|
void WaylandVsyncSource::WaylandDisplay::MaybeUpdateSource(
|
|
|
|
const RefPtr<NativeLayerRootWayland>& aNativeLayerRoot) {
|
|
|
|
MutexAutoLock lock(mMutex);
|
|
|
|
|
|
|
|
if (aNativeLayerRoot == mNativeLayerRoot) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
mNativeLayerRoot = aNativeLayerRoot;
|
|
|
|
mContainer = nullptr;
|
|
|
|
|
|
|
|
if (mMonitorEnabled) {
|
|
|
|
mCallbackRequested = false;
|
2021-09-08 03:04:09 +03:00
|
|
|
Refresh(lock);
|
2020-06-05 02:39:30 +03:00
|
|
|
}
|
2020-06-05 04:31:45 +03:00
|
|
|
}
|
2019-11-27 03:21:33 +03:00
|
|
|
|
2021-09-08 03:04:09 +03:00
|
|
|
void WaylandVsyncSource::WaylandDisplay::Refresh(
|
|
|
|
const MutexAutoLock& aProofOfLock) {
|
Bug 1711244 - Integrate NativeLayerWayland with WaylandVsyncSource, r=stransky,gfx-reviewers,jrmuizel
Make the vsync source request frame callbacks from opaque native
layers. This is necessary as opaque layers may occlude the
MozContainer surface, which is normally used for frame callbacks.
Wayland compositors may (and are encouraged to) optimize away
such callbacks, so we need to make sure to request frame callbacks
from actually visible surfaces.
Callbacks are requested for all layers, but only the first callback
will trigger the vsync source.
In order to get this right concerning multiple requested callbacks,
possibly being called from different threads etc., introduce a
callback abstraction, `CallbackMultiplexHelper`, to make this simple
to handle for callers.
Differential Revision: https://phabricator.services.mozilla.com/D116026
2021-06-10 18:12:54 +03:00
|
|
|
if (!(mContainer || mNativeLayerRoot) || !mMonitorEnabled || !mVsyncEnabled ||
|
|
|
|
mCallbackRequested) {
|
|
|
|
// We don't need to do anything because:
|
|
|
|
// * We are unwanted by our widget or monitor, or
|
|
|
|
// * The last frame callback hasn't yet run to see that it had been shut
|
|
|
|
// down, so we can reuse it after having set mVsyncEnabled to true.
|
|
|
|
return;
|
|
|
|
}
|
2020-06-05 04:31:45 +03:00
|
|
|
|
Bug 1711244 - Integrate NativeLayerWayland with WaylandVsyncSource, r=stransky,gfx-reviewers,jrmuizel
Make the vsync source request frame callbacks from opaque native
layers. This is necessary as opaque layers may occlude the
MozContainer surface, which is normally used for frame callbacks.
Wayland compositors may (and are encouraged to) optimize away
such callbacks, so we need to make sure to request frame callbacks
from actually visible surfaces.
Callbacks are requested for all layers, but only the first callback
will trigger the vsync source.
In order to get this right concerning multiple requested callbacks,
possibly being called from different threads etc., introduce a
callback abstraction, `CallbackMultiplexHelper`, to make this simple
to handle for callers.
Differential Revision: https://phabricator.services.mozilla.com/D116026
2021-06-10 18:12:54 +03:00
|
|
|
if (mContainer) {
|
2020-11-03 14:39:18 +03:00
|
|
|
struct wl_surface* surface = moz_container_wayland_surface_lock(mContainer);
|
|
|
|
if (!surface) {
|
|
|
|
// The surface hasn't been created yet. Try again when the surface is
|
|
|
|
// ready.
|
|
|
|
RefPtr<WaylandVsyncSource::WaylandDisplay> self(this);
|
|
|
|
moz_container_wayland_add_initial_draw_callback(
|
Bug 1711244 - Integrate NativeLayerWayland with WaylandVsyncSource, r=stransky,gfx-reviewers,jrmuizel
Make the vsync source request frame callbacks from opaque native
layers. This is necessary as opaque layers may occlude the
MozContainer surface, which is normally used for frame callbacks.
Wayland compositors may (and are encouraged to) optimize away
such callbacks, so we need to make sure to request frame callbacks
from actually visible surfaces.
Callbacks are requested for all layers, but only the first callback
will trigger the vsync source.
In order to get this right concerning multiple requested callbacks,
possibly being called from different threads etc., introduce a
callback abstraction, `CallbackMultiplexHelper`, to make this simple
to handle for callers.
Differential Revision: https://phabricator.services.mozilla.com/D116026
2021-06-10 18:12:54 +03:00
|
|
|
mContainer, [self]() -> void {
|
|
|
|
MutexAutoLock lock(self->mMutex);
|
2021-09-08 03:04:09 +03:00
|
|
|
self->Refresh(lock);
|
Bug 1711244 - Integrate NativeLayerWayland with WaylandVsyncSource, r=stransky,gfx-reviewers,jrmuizel
Make the vsync source request frame callbacks from opaque native
layers. This is necessary as opaque layers may occlude the
MozContainer surface, which is normally used for frame callbacks.
Wayland compositors may (and are encouraged to) optimize away
such callbacks, so we need to make sure to request frame callbacks
from actually visible surfaces.
Callbacks are requested for all layers, but only the first callback
will trigger the vsync source.
In order to get this right concerning multiple requested callbacks,
possibly being called from different threads etc., introduce a
callback abstraction, `CallbackMultiplexHelper`, to make this simple
to handle for callers.
Differential Revision: https://phabricator.services.mozilla.com/D116026
2021-06-10 18:12:54 +03:00
|
|
|
});
|
2020-11-03 14:39:18 +03:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
moz_container_wayland_surface_unlock(mContainer, &surface);
|
Bug 1711244 - Integrate NativeLayerWayland with WaylandVsyncSource, r=stransky,gfx-reviewers,jrmuizel
Make the vsync source request frame callbacks from opaque native
layers. This is necessary as opaque layers may occlude the
MozContainer surface, which is normally used for frame callbacks.
Wayland compositors may (and are encouraged to) optimize away
such callbacks, so we need to make sure to request frame callbacks
from actually visible surfaces.
Callbacks are requested for all layers, but only the first callback
will trigger the vsync source.
In order to get this right concerning multiple requested callbacks,
possibly being called from different threads etc., introduce a
callback abstraction, `CallbackMultiplexHelper`, to make this simple
to handle for callers.
Differential Revision: https://phabricator.services.mozilla.com/D116026
2021-06-10 18:12:54 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
// Vsync is enabled, but we don't have a callback configured. Set one up so
|
|
|
|
// we can get to work.
|
2021-09-08 03:04:09 +03:00
|
|
|
SetupFrameCallback(aProofOfLock);
|
Bug 1711244 - Integrate NativeLayerWayland with WaylandVsyncSource, r=stransky,gfx-reviewers,jrmuizel
Make the vsync source request frame callbacks from opaque native
layers. This is necessary as opaque layers may occlude the
MozContainer surface, which is normally used for frame callbacks.
Wayland compositors may (and are encouraged to) optimize away
such callbacks, so we need to make sure to request frame callbacks
from actually visible surfaces.
Callbacks are requested for all layers, but only the first callback
will trigger the vsync source.
In order to get this right concerning multiple requested callbacks,
possibly being called from different threads etc., introduce a
callback abstraction, `CallbackMultiplexHelper`, to make this simple
to handle for callers.
Differential Revision: https://phabricator.services.mozilla.com/D116026
2021-06-10 18:12:54 +03:00
|
|
|
mLastVsyncTimeStamp = TimeStamp::Now();
|
|
|
|
TimeStamp outputTimestamp = mLastVsyncTimeStamp + GetVsyncRate();
|
2019-11-27 03:21:33 +03:00
|
|
|
|
Bug 1711244 - Integrate NativeLayerWayland with WaylandVsyncSource, r=stransky,gfx-reviewers,jrmuizel
Make the vsync source request frame callbacks from opaque native
layers. This is necessary as opaque layers may occlude the
MozContainer surface, which is normally used for frame callbacks.
Wayland compositors may (and are encouraged to) optimize away
such callbacks, so we need to make sure to request frame callbacks
from actually visible surfaces.
Callbacks are requested for all layers, but only the first callback
will trigger the vsync source.
In order to get this right concerning multiple requested callbacks,
possibly being called from different threads etc., introduce a
callback abstraction, `CallbackMultiplexHelper`, to make this simple
to handle for callers.
Differential Revision: https://phabricator.services.mozilla.com/D116026
2021-06-10 18:12:54 +03:00
|
|
|
{
|
|
|
|
MutexAutoUnlock unlock(mMutex);
|
|
|
|
NotifyVsync(mLastVsyncTimeStamp, outputTimestamp);
|
2020-11-03 14:39:18 +03:00
|
|
|
}
|
2019-11-27 03:21:33 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
void WaylandVsyncSource::WaylandDisplay::EnableMonitor() {
|
Bug 1711244 - Integrate NativeLayerWayland with WaylandVsyncSource, r=stransky,gfx-reviewers,jrmuizel
Make the vsync source request frame callbacks from opaque native
layers. This is necessary as opaque layers may occlude the
MozContainer surface, which is normally used for frame callbacks.
Wayland compositors may (and are encouraged to) optimize away
such callbacks, so we need to make sure to request frame callbacks
from actually visible surfaces.
Callbacks are requested for all layers, but only the first callback
will trigger the vsync source.
In order to get this right concerning multiple requested callbacks,
possibly being called from different threads etc., introduce a
callback abstraction, `CallbackMultiplexHelper`, to make this simple
to handle for callers.
Differential Revision: https://phabricator.services.mozilla.com/D116026
2021-06-10 18:12:54 +03:00
|
|
|
MutexAutoLock lock(mMutex);
|
|
|
|
if (mMonitorEnabled) {
|
|
|
|
return;
|
2019-11-27 03:21:33 +03:00
|
|
|
}
|
Bug 1711244 - Integrate NativeLayerWayland with WaylandVsyncSource, r=stransky,gfx-reviewers,jrmuizel
Make the vsync source request frame callbacks from opaque native
layers. This is necessary as opaque layers may occlude the
MozContainer surface, which is normally used for frame callbacks.
Wayland compositors may (and are encouraged to) optimize away
such callbacks, so we need to make sure to request frame callbacks
from actually visible surfaces.
Callbacks are requested for all layers, but only the first callback
will trigger the vsync source.
In order to get this right concerning multiple requested callbacks,
possibly being called from different threads etc., introduce a
callback abstraction, `CallbackMultiplexHelper`, to make this simple
to handle for callers.
Differential Revision: https://phabricator.services.mozilla.com/D116026
2021-06-10 18:12:54 +03:00
|
|
|
mMonitorEnabled = true;
|
2021-09-08 03:04:09 +03:00
|
|
|
Refresh(lock);
|
2019-11-27 03:21:33 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
void WaylandVsyncSource::WaylandDisplay::DisableMonitor() {
|
Bug 1711244 - Integrate NativeLayerWayland with WaylandVsyncSource, r=stransky,gfx-reviewers,jrmuizel
Make the vsync source request frame callbacks from opaque native
layers. This is necessary as opaque layers may occlude the
MozContainer surface, which is normally used for frame callbacks.
Wayland compositors may (and are encouraged to) optimize away
such callbacks, so we need to make sure to request frame callbacks
from actually visible surfaces.
Callbacks are requested for all layers, but only the first callback
will trigger the vsync source.
In order to get this right concerning multiple requested callbacks,
possibly being called from different threads etc., introduce a
callback abstraction, `CallbackMultiplexHelper`, to make this simple
to handle for callers.
Differential Revision: https://phabricator.services.mozilla.com/D116026
2021-06-10 18:12:54 +03:00
|
|
|
MutexAutoLock lock(mMutex);
|
2019-11-27 03:21:33 +03:00
|
|
|
if (!mMonitorEnabled) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
mMonitorEnabled = false;
|
Bug 1711244 - Integrate NativeLayerWayland with WaylandVsyncSource, r=stransky,gfx-reviewers,jrmuizel
Make the vsync source request frame callbacks from opaque native
layers. This is necessary as opaque layers may occlude the
MozContainer surface, which is normally used for frame callbacks.
Wayland compositors may (and are encouraged to) optimize away
such callbacks, so we need to make sure to request frame callbacks
from actually visible surfaces.
Callbacks are requested for all layers, but only the first callback
will trigger the vsync source.
In order to get this right concerning multiple requested callbacks,
possibly being called from different threads etc., introduce a
callback abstraction, `CallbackMultiplexHelper`, to make this simple
to handle for callers.
Differential Revision: https://phabricator.services.mozilla.com/D116026
2021-06-10 18:12:54 +03:00
|
|
|
mCallbackRequested = false;
|
2019-11-27 03:21:33 +03:00
|
|
|
}
|
|
|
|
|
2021-09-08 03:04:09 +03:00
|
|
|
void WaylandVsyncSource::WaylandDisplay::SetupFrameCallback(
|
|
|
|
const MutexAutoLock& aProofOfLock) {
|
Bug 1711244 - Integrate NativeLayerWayland with WaylandVsyncSource, r=stransky,gfx-reviewers,jrmuizel
Make the vsync source request frame callbacks from opaque native
layers. This is necessary as opaque layers may occlude the
MozContainer surface, which is normally used for frame callbacks.
Wayland compositors may (and are encouraged to) optimize away
such callbacks, so we need to make sure to request frame callbacks
from actually visible surfaces.
Callbacks are requested for all layers, but only the first callback
will trigger the vsync source.
In order to get this right concerning multiple requested callbacks,
possibly being called from different threads etc., introduce a
callback abstraction, `CallbackMultiplexHelper`, to make this simple
to handle for callers.
Differential Revision: https://phabricator.services.mozilla.com/D116026
2021-06-10 18:12:54 +03:00
|
|
|
MOZ_ASSERT(!mCallbackRequested);
|
|
|
|
|
|
|
|
if (mNativeLayerRoot) {
|
|
|
|
mNativeLayerRoot->RequestFrameCallback(&WaylandVsyncSourceCallbackHandler,
|
|
|
|
this);
|
|
|
|
} else {
|
|
|
|
struct wl_surface* surface = moz_container_wayland_surface_lock(mContainer);
|
|
|
|
if (!surface) {
|
|
|
|
// We don't have a surface, either due to being called before it was made
|
|
|
|
// available in the mozcontainer, or after it was destroyed. We're all
|
|
|
|
// done regardless.
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
wl_callback* callback = wl_surface_frame(surface);
|
|
|
|
wl_callback_add_listener(callback, &WaylandVsyncSourceCallbackListener,
|
|
|
|
this);
|
|
|
|
wl_surface_commit(surface);
|
2021-09-08 03:04:09 +03:00
|
|
|
wl_display_flush(WaylandDisplayGet()->GetDisplay());
|
Bug 1711244 - Integrate NativeLayerWayland with WaylandVsyncSource, r=stransky,gfx-reviewers,jrmuizel
Make the vsync source request frame callbacks from opaque native
layers. This is necessary as opaque layers may occlude the
MozContainer surface, which is normally used for frame callbacks.
Wayland compositors may (and are encouraged to) optimize away
such callbacks, so we need to make sure to request frame callbacks
from actually visible surfaces.
Callbacks are requested for all layers, but only the first callback
will trigger the vsync source.
In order to get this right concerning multiple requested callbacks,
possibly being called from different threads etc., introduce a
callback abstraction, `CallbackMultiplexHelper`, to make this simple
to handle for callers.
Differential Revision: https://phabricator.services.mozilla.com/D116026
2021-06-10 18:12:54 +03:00
|
|
|
moz_container_wayland_surface_unlock(mContainer, &surface);
|
2019-11-27 03:21:33 +03:00
|
|
|
}
|
|
|
|
|
Bug 1711244 - Integrate NativeLayerWayland with WaylandVsyncSource, r=stransky,gfx-reviewers,jrmuizel
Make the vsync source request frame callbacks from opaque native
layers. This is necessary as opaque layers may occlude the
MozContainer surface, which is normally used for frame callbacks.
Wayland compositors may (and are encouraged to) optimize away
such callbacks, so we need to make sure to request frame callbacks
from actually visible surfaces.
Callbacks are requested for all layers, but only the first callback
will trigger the vsync source.
In order to get this right concerning multiple requested callbacks,
possibly being called from different threads etc., introduce a
callback abstraction, `CallbackMultiplexHelper`, to make this simple
to handle for callers.
Differential Revision: https://phabricator.services.mozilla.com/D116026
2021-06-10 18:12:54 +03:00
|
|
|
mCallbackRequested = true;
|
2019-11-27 03:21:33 +03:00
|
|
|
}
|
|
|
|
|
2021-09-08 03:04:09 +03:00
|
|
|
void WaylandVsyncSource::WaylandDisplay::FrameCallback(uint32_t aTime) {
|
Bug 1711244 - Integrate NativeLayerWayland with WaylandVsyncSource, r=stransky,gfx-reviewers,jrmuizel
Make the vsync source request frame callbacks from opaque native
layers. This is necessary as opaque layers may occlude the
MozContainer surface, which is normally used for frame callbacks.
Wayland compositors may (and are encouraged to) optimize away
such callbacks, so we need to make sure to request frame callbacks
from actually visible surfaces.
Callbacks are requested for all layers, but only the first callback
will trigger the vsync source.
In order to get this right concerning multiple requested callbacks,
possibly being called from different threads etc., introduce a
callback abstraction, `CallbackMultiplexHelper`, to make this simple
to handle for callers.
Differential Revision: https://phabricator.services.mozilla.com/D116026
2021-06-10 18:12:54 +03:00
|
|
|
MutexAutoLock lock(mMutex);
|
|
|
|
mCallbackRequested = false;
|
2019-11-27 03:21:33 +03:00
|
|
|
|
Bug 1711244 - Integrate NativeLayerWayland with WaylandVsyncSource, r=stransky,gfx-reviewers,jrmuizel
Make the vsync source request frame callbacks from opaque native
layers. This is necessary as opaque layers may occlude the
MozContainer surface, which is normally used for frame callbacks.
Wayland compositors may (and are encouraged to) optimize away
such callbacks, so we need to make sure to request frame callbacks
from actually visible surfaces.
Callbacks are requested for all layers, but only the first callback
will trigger the vsync source.
In order to get this right concerning multiple requested callbacks,
possibly being called from different threads etc., introduce a
callback abstraction, `CallbackMultiplexHelper`, to make this simple
to handle for callers.
Differential Revision: https://phabricator.services.mozilla.com/D116026
2021-06-10 18:12:54 +03:00
|
|
|
if (!mVsyncEnabled || !mMonitorEnabled) {
|
|
|
|
// We are unwanted by either our creator or our consumer, so we just stop
|
|
|
|
// here without setting up a new frame callback.
|
|
|
|
return;
|
|
|
|
}
|
2019-11-27 03:21:33 +03:00
|
|
|
|
Bug 1711244 - Integrate NativeLayerWayland with WaylandVsyncSource, r=stransky,gfx-reviewers,jrmuizel
Make the vsync source request frame callbacks from opaque native
layers. This is necessary as opaque layers may occlude the
MozContainer surface, which is normally used for frame callbacks.
Wayland compositors may (and are encouraged to) optimize away
such callbacks, so we need to make sure to request frame callbacks
from actually visible surfaces.
Callbacks are requested for all layers, but only the first callback
will trigger the vsync source.
In order to get this right concerning multiple requested callbacks,
possibly being called from different threads etc., introduce a
callback abstraction, `CallbackMultiplexHelper`, to make this simple
to handle for callers.
Differential Revision: https://phabricator.services.mozilla.com/D116026
2021-06-10 18:12:54 +03:00
|
|
|
// Configure our next frame callback.
|
2021-09-08 03:04:09 +03:00
|
|
|
SetupFrameCallback(lock);
|
2020-11-03 14:39:18 +03:00
|
|
|
|
2021-09-08 03:04:09 +03:00
|
|
|
int64_t tick = BaseTimeDurationPlatformUtils::TicksFromMilliseconds(aTime);
|
Bug 1711244 - Integrate NativeLayerWayland with WaylandVsyncSource, r=stransky,gfx-reviewers,jrmuizel
Make the vsync source request frame callbacks from opaque native
layers. This is necessary as opaque layers may occlude the
MozContainer surface, which is normally used for frame callbacks.
Wayland compositors may (and are encouraged to) optimize away
such callbacks, so we need to make sure to request frame callbacks
from actually visible surfaces.
Callbacks are requested for all layers, but only the first callback
will trigger the vsync source.
In order to get this right concerning multiple requested callbacks,
possibly being called from different threads etc., introduce a
callback abstraction, `CallbackMultiplexHelper`, to make this simple
to handle for callers.
Differential Revision: https://phabricator.services.mozilla.com/D116026
2021-06-10 18:12:54 +03:00
|
|
|
TimeStamp callbackTimeStamp = TimeStamp::FromSystemTime(tick);
|
|
|
|
double duration = (TimeStamp::Now() - callbackTimeStamp).ToMilliseconds();
|
2020-11-03 14:39:18 +03:00
|
|
|
|
Bug 1711244 - Integrate NativeLayerWayland with WaylandVsyncSource, r=stransky,gfx-reviewers,jrmuizel
Make the vsync source request frame callbacks from opaque native
layers. This is necessary as opaque layers may occlude the
MozContainer surface, which is normally used for frame callbacks.
Wayland compositors may (and are encouraged to) optimize away
such callbacks, so we need to make sure to request frame callbacks
from actually visible surfaces.
Callbacks are requested for all layers, but only the first callback
will trigger the vsync source.
In order to get this right concerning multiple requested callbacks,
possibly being called from different threads etc., introduce a
callback abstraction, `CallbackMultiplexHelper`, to make this simple
to handle for callers.
Differential Revision: https://phabricator.services.mozilla.com/D116026
2021-06-10 18:12:54 +03:00
|
|
|
TimeStamp vsyncTimestamp;
|
|
|
|
if (duration < 50 && duration > -50) {
|
|
|
|
vsyncTimestamp = callbackTimeStamp;
|
|
|
|
} else {
|
|
|
|
vsyncTimestamp = TimeStamp::Now();
|
|
|
|
}
|
2020-11-03 14:39:18 +03:00
|
|
|
|
2021-09-08 03:04:09 +03:00
|
|
|
CalculateVsyncRate(lock, vsyncTimestamp);
|
Bug 1711244 - Integrate NativeLayerWayland with WaylandVsyncSource, r=stransky,gfx-reviewers,jrmuizel
Make the vsync source request frame callbacks from opaque native
layers. This is necessary as opaque layers may occlude the
MozContainer surface, which is normally used for frame callbacks.
Wayland compositors may (and are encouraged to) optimize away
such callbacks, so we need to make sure to request frame callbacks
from actually visible surfaces.
Callbacks are requested for all layers, but only the first callback
will trigger the vsync source.
In order to get this right concerning multiple requested callbacks,
possibly being called from different threads etc., introduce a
callback abstraction, `CallbackMultiplexHelper`, to make this simple
to handle for callers.
Differential Revision: https://phabricator.services.mozilla.com/D116026
2021-06-10 18:12:54 +03:00
|
|
|
mLastVsyncTimeStamp = vsyncTimestamp;
|
|
|
|
TimeStamp outputTimestamp = vsyncTimestamp + GetVsyncRate();
|
|
|
|
|
|
|
|
{
|
|
|
|
MutexAutoUnlock unlock(mMutex);
|
|
|
|
NotifyVsync(mLastVsyncTimeStamp, outputTimestamp);
|
2019-11-27 03:21:33 +03:00
|
|
|
}
|
2020-11-03 14:39:18 +03:00
|
|
|
}
|
2019-11-27 03:21:33 +03:00
|
|
|
|
2020-11-03 14:39:18 +03:00
|
|
|
TimeDuration WaylandVsyncSource::WaylandDisplay::GetVsyncRate() {
|
|
|
|
return mVsyncRate;
|
|
|
|
}
|
|
|
|
|
|
|
|
void WaylandVsyncSource::WaylandDisplay::CalculateVsyncRate(
|
2021-09-08 03:04:09 +03:00
|
|
|
const MutexAutoLock& aProofOfLock, TimeStamp aVsyncTimestamp) {
|
|
|
|
double duration = (aVsyncTimestamp - mLastVsyncTimeStamp).ToMilliseconds();
|
2020-11-03 14:39:18 +03:00
|
|
|
double curVsyncRate = mVsyncRate.ToMilliseconds();
|
|
|
|
|
|
|
|
if (duration > curVsyncRate) {
|
2021-09-08 03:04:09 +03:00
|
|
|
double correction = fmin(curVsyncRate, (duration - curVsyncRate) / 10);
|
2020-11-03 14:39:18 +03:00
|
|
|
mVsyncRate += TimeDuration::FromMilliseconds(correction);
|
|
|
|
} else {
|
2021-09-08 03:04:09 +03:00
|
|
|
double correction = fmin(curVsyncRate / 2, (curVsyncRate - duration) / 10);
|
2020-11-03 14:39:18 +03:00
|
|
|
mVsyncRate -= TimeDuration::FromMilliseconds(correction);
|
|
|
|
}
|
2019-11-27 03:21:33 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
void WaylandVsyncSource::WaylandDisplay::EnableVsync() {
|
|
|
|
MOZ_ASSERT(NS_IsMainThread());
|
Bug 1711244 - Integrate NativeLayerWayland with WaylandVsyncSource, r=stransky,gfx-reviewers,jrmuizel
Make the vsync source request frame callbacks from opaque native
layers. This is necessary as opaque layers may occlude the
MozContainer surface, which is normally used for frame callbacks.
Wayland compositors may (and are encouraged to) optimize away
such callbacks, so we need to make sure to request frame callbacks
from actually visible surfaces.
Callbacks are requested for all layers, but only the first callback
will trigger the vsync source.
In order to get this right concerning multiple requested callbacks,
possibly being called from different threads etc., introduce a
callback abstraction, `CallbackMultiplexHelper`, to make this simple
to handle for callers.
Differential Revision: https://phabricator.services.mozilla.com/D116026
2021-06-10 18:12:54 +03:00
|
|
|
MutexAutoLock lock(mMutex);
|
|
|
|
if (mVsyncEnabled || mIsShutdown) {
|
|
|
|
return;
|
2019-11-27 03:21:33 +03:00
|
|
|
}
|
Bug 1711244 - Integrate NativeLayerWayland with WaylandVsyncSource, r=stransky,gfx-reviewers,jrmuizel
Make the vsync source request frame callbacks from opaque native
layers. This is necessary as opaque layers may occlude the
MozContainer surface, which is normally used for frame callbacks.
Wayland compositors may (and are encouraged to) optimize away
such callbacks, so we need to make sure to request frame callbacks
from actually visible surfaces.
Callbacks are requested for all layers, but only the first callback
will trigger the vsync source.
In order to get this right concerning multiple requested callbacks,
possibly being called from different threads etc., introduce a
callback abstraction, `CallbackMultiplexHelper`, to make this simple
to handle for callers.
Differential Revision: https://phabricator.services.mozilla.com/D116026
2021-06-10 18:12:54 +03:00
|
|
|
mVsyncEnabled = true;
|
2021-09-08 03:04:09 +03:00
|
|
|
Refresh(lock);
|
2019-11-27 03:21:33 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
void WaylandVsyncSource::WaylandDisplay::DisableVsync() {
|
Bug 1711244 - Integrate NativeLayerWayland with WaylandVsyncSource, r=stransky,gfx-reviewers,jrmuizel
Make the vsync source request frame callbacks from opaque native
layers. This is necessary as opaque layers may occlude the
MozContainer surface, which is normally used for frame callbacks.
Wayland compositors may (and are encouraged to) optimize away
such callbacks, so we need to make sure to request frame callbacks
from actually visible surfaces.
Callbacks are requested for all layers, but only the first callback
will trigger the vsync source.
In order to get this right concerning multiple requested callbacks,
possibly being called from different threads etc., introduce a
callback abstraction, `CallbackMultiplexHelper`, to make this simple
to handle for callers.
Differential Revision: https://phabricator.services.mozilla.com/D116026
2021-06-10 18:12:54 +03:00
|
|
|
MutexAutoLock lock(mMutex);
|
2019-11-27 03:21:33 +03:00
|
|
|
mVsyncEnabled = false;
|
Bug 1711244 - Integrate NativeLayerWayland with WaylandVsyncSource, r=stransky,gfx-reviewers,jrmuizel
Make the vsync source request frame callbacks from opaque native
layers. This is necessary as opaque layers may occlude the
MozContainer surface, which is normally used for frame callbacks.
Wayland compositors may (and are encouraged to) optimize away
such callbacks, so we need to make sure to request frame callbacks
from actually visible surfaces.
Callbacks are requested for all layers, but only the first callback
will trigger the vsync source.
In order to get this right concerning multiple requested callbacks,
possibly being called from different threads etc., introduce a
callback abstraction, `CallbackMultiplexHelper`, to make this simple
to handle for callers.
Differential Revision: https://phabricator.services.mozilla.com/D116026
2021-06-10 18:12:54 +03:00
|
|
|
mCallbackRequested = false;
|
2019-11-27 03:21:33 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
bool WaylandVsyncSource::WaylandDisplay::IsVsyncEnabled() {
|
Bug 1711244 - Integrate NativeLayerWayland with WaylandVsyncSource, r=stransky,gfx-reviewers,jrmuizel
Make the vsync source request frame callbacks from opaque native
layers. This is necessary as opaque layers may occlude the
MozContainer surface, which is normally used for frame callbacks.
Wayland compositors may (and are encouraged to) optimize away
such callbacks, so we need to make sure to request frame callbacks
from actually visible surfaces.
Callbacks are requested for all layers, but only the first callback
will trigger the vsync source.
In order to get this right concerning multiple requested callbacks,
possibly being called from different threads etc., introduce a
callback abstraction, `CallbackMultiplexHelper`, to make this simple
to handle for callers.
Differential Revision: https://phabricator.services.mozilla.com/D116026
2021-06-10 18:12:54 +03:00
|
|
|
MutexAutoLock lock(mMutex);
|
2019-11-27 03:21:33 +03:00
|
|
|
return mVsyncEnabled;
|
|
|
|
}
|
|
|
|
|
|
|
|
void WaylandVsyncSource::WaylandDisplay::Shutdown() {
|
|
|
|
MOZ_ASSERT(NS_IsMainThread());
|
Bug 1711244 - Integrate NativeLayerWayland with WaylandVsyncSource, r=stransky,gfx-reviewers,jrmuizel
Make the vsync source request frame callbacks from opaque native
layers. This is necessary as opaque layers may occlude the
MozContainer surface, which is normally used for frame callbacks.
Wayland compositors may (and are encouraged to) optimize away
such callbacks, so we need to make sure to request frame callbacks
from actually visible surfaces.
Callbacks are requested for all layers, but only the first callback
will trigger the vsync source.
In order to get this right concerning multiple requested callbacks,
possibly being called from different threads etc., introduce a
callback abstraction, `CallbackMultiplexHelper`, to make this simple
to handle for callers.
Differential Revision: https://phabricator.services.mozilla.com/D116026
2021-06-10 18:12:54 +03:00
|
|
|
MutexAutoLock lock(mMutex);
|
2021-07-13 16:44:12 +03:00
|
|
|
mContainer = nullptr;
|
|
|
|
mNativeLayerRoot = nullptr;
|
2020-11-03 14:38:35 +03:00
|
|
|
mIsShutdown = true;
|
|
|
|
mVsyncEnabled = false;
|
Bug 1711244 - Integrate NativeLayerWayland with WaylandVsyncSource, r=stransky,gfx-reviewers,jrmuizel
Make the vsync source request frame callbacks from opaque native
layers. This is necessary as opaque layers may occlude the
MozContainer surface, which is normally used for frame callbacks.
Wayland compositors may (and are encouraged to) optimize away
such callbacks, so we need to make sure to request frame callbacks
from actually visible surfaces.
Callbacks are requested for all layers, but only the first callback
will trigger the vsync source.
In order to get this right concerning multiple requested callbacks,
possibly being called from different threads etc., introduce a
callback abstraction, `CallbackMultiplexHelper`, to make this simple
to handle for callers.
Differential Revision: https://phabricator.services.mozilla.com/D116026
2021-06-10 18:12:54 +03:00
|
|
|
mCallbackRequested = false;
|
2019-11-27 03:21:33 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
} // namespace mozilla
|
|
|
|
|
|
|
|
#endif // MOZ_WAYLAND
|