Files
moonlight-qt/app/streaming/video/ffmpeg-renderers/pacer/waylandvsyncsource.cpp
2025-01-30 22:41:40 -06:00

66 lines
1.6 KiB
C++

#include "waylandvsyncsource.h"
#ifndef SDL_VIDEO_DRIVER_WAYLAND
#warning Unable to use WaylandVsyncSource without SDL support
#else
const struct wl_callback_listener WaylandVsyncSource::s_FrameListener = {
.done = WaylandVsyncSource::frameDone,
};
WaylandVsyncSource::WaylandVsyncSource(Pacer* pacer)
: m_Pacer(pacer),
m_Display(nullptr),
m_Surface(nullptr),
m_Callback(nullptr)
{
}
WaylandVsyncSource::~WaylandVsyncSource()
{
if (m_Callback != nullptr) {
wl_callback_destroy(m_Callback);
wl_display_roundtrip(m_Display);
}
}
bool WaylandVsyncSource::initialize(SDL_Window* window, int)
{
m_Display = (wl_display*)SDLC_Wayland_GetDisplay(window);
m_Surface = (wl_surface*)SDLC_Wayland_GetSurface(window);
// Enqueue our first frame callback
m_Callback = wl_surface_frame(m_Surface);
wl_callback_add_listener(m_Callback, &s_FrameListener, this);
wl_surface_commit(m_Surface);
return true;
}
bool WaylandVsyncSource::isAsync()
{
// Wayland frame callbacks are asynchronous
return true;
}
void WaylandVsyncSource::frameDone(void* data, struct wl_callback* oldCb, uint32_t)
{
auto me = (WaylandVsyncSource*)data;
// Free this callback
SDL_assert(oldCb == me->m_Callback);
wl_callback_destroy(oldCb);
// Wake the Pacer Vsync thread
me->m_Pacer->signalVsync();
// Register for another callback
me->m_Callback = wl_surface_frame(me->m_Surface);
wl_callback_add_listener(me->m_Callback, &s_FrameListener, data);
wl_surface_commit(me->m_Surface);
wl_display_flush(me->m_Display);
}
#endif