fune/widget/gtk/WaylandVsyncSource.h
Robert Mader a715823143 Bug 1670444 - [Wayland] Some vsyncsource improvements, r=stransky
This implements the following three things:
 - use the frame callback timestamp. While there are few guarantees about
its behaviour, it still seems to make sense to use it assuming: a) the compositor
uses monotonic system time (we do a simple sanity check) b) the compositor is
more likely to run at high priority, thus making the offset from the actual
vsync less jittery c) the timestamp is closer to the actual vsync event,
making it more fitting for how we use it internally
 - implement a very simplistic estimate of the refresh interval.
Since bug 1653737 WR takes an estimated next output time to optimize
for. Until now this was hardcoded to 16.6ms from the last `Now()`. Now
we adjust the value on each interval slightly, making it much more
precise on non-60Hz refresh rates (this certainly can get improved more)
 - Shuffle around mutex looking a bit, making sure we don't hold it
while calling `NotifyVsync()`. That should make it less likely to run
into deadlock conditions.

Depends on D95515

Differential Revision: https://phabricator.services.mozilla.com/D93169
2020-11-03 11:39:18 +00:00

96 lines
3 KiB
C++

/* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 2 -*-
* 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 _WaylandVsyncSource_h_
#define _WaylandVsyncSource_h_
#include "mozilla/RefPtr.h"
#include "mozilla/Mutex.h"
#include "mozilla/Monitor.h"
#include "MozContainer.h"
#include "VsyncSource.h"
#include "base/thread.h"
#include "nsWaylandDisplay.h"
namespace mozilla {
/*
* WaylandVsyncSource
*
* This class provides a per-widget VsyncSource under Wayland, emulated using
* frame callbacks on the widget surface with empty surface commits.
*
* Wayland does not expose vsync/vblank, as it considers that an implementation
* detail the clients should not concern themselves with. Instead, frame
* callbacks are provided whenever the compositor believes it is a good time to
* start drawing the next frame for a particular surface, giving us as much
* time as possible to do so.
*
* Note that the compositor sends frame callbacks only when it sees fit, and
* when that may be is entirely up to the compositor. One cannot expect a
* certain rate of callbacks, or any callbacks at all. Examples of common
* variations would be surfaces moved between outputs with different refresh
* rates, and surfaces that are hidden and therefore do not receieve any
* callbacks at all. Other hypothetical scenarios of variation could be
* throttling to conserve power, or because a user has requested it.
*
*/
class WaylandVsyncSource final : public gfx::VsyncSource {
public:
explicit WaylandVsyncSource(MozContainer* container) {
MOZ_ASSERT(NS_IsMainThread());
mGlobalDisplay = new WaylandDisplay(container);
}
virtual ~WaylandVsyncSource() { MOZ_ASSERT(NS_IsMainThread()); }
virtual Display& GetGlobalDisplay() override { return *mGlobalDisplay; }
class WaylandDisplay final : public mozilla::gfx::VsyncSource::Display {
public:
explicit WaylandDisplay(MozContainer* container);
void EnableMonitor();
void DisableMonitor();
void FrameCallback(uint32_t timestampTime);
void Notify();
TimeDuration GetVsyncRate() override;
virtual void EnableVsync() override;
virtual void DisableVsync() override;
virtual bool IsVsyncEnabled() override;
virtual void Shutdown() override;
private:
virtual ~WaylandDisplay() = default;
void Refresh();
void SetupFrameCallback();
void ClearFrameCallback();
void CalculateVsyncRate(TimeStamp vsyncTimestamp);
Mutex mEnabledLock;
bool mIsShutdown;
bool mVsyncEnabled;
bool mMonitorEnabled;
struct wl_display* mDisplay;
struct wl_callback* mCallback;
MozContainer* mContainer;
TimeDuration mVsyncRate;
TimeStamp mLastVsyncTimeStamp;
};
private:
// We need a refcounted VsyncSource::Display to use chromium IPC runnables.
RefPtr<WaylandDisplay> mGlobalDisplay;
};
} // namespace mozilla
#endif // _WaylandVsyncSource_h_