diff options
Diffstat (limited to '')
-rw-r--r-- | widget/gtk/WaylandVsyncSource.h | 96 |
1 files changed, 96 insertions, 0 deletions
diff --git a/widget/gtk/WaylandVsyncSource.h b/widget/gtk/WaylandVsyncSource.h new file mode 100644 index 0000000000..fc6fcc10cf --- /dev/null +++ b/widget/gtk/WaylandVsyncSource.h @@ -0,0 +1,96 @@ +/* -*- 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_ |