mirror of
https://github.com/glfw/glfw.git
synced 2025-10-03 13:20:58 +00:00
Merge b6d3b50275
into fa60269245
This commit is contained in:
commit
ee341ee061
@ -413,6 +413,31 @@ GLFWAPI struct wl_output* glfwGetWaylandMonitor(GLFWmonitor* monitor);
|
||||
* @ingroup native
|
||||
*/
|
||||
GLFWAPI struct wl_surface* glfwGetWaylandWindow(GLFWwindow* window);
|
||||
|
||||
/*! @brief Check to see if the Wayland server supports the presentation-time
|
||||
* protocol.
|
||||
*
|
||||
* @return GLFW_TRUE iff presentation-time is supported.
|
||||
*
|
||||
* @since Added in version 3.3.
|
||||
*
|
||||
* @ingroup native
|
||||
*/
|
||||
GLFWAPI int glfwWaylandPresSupported(void);
|
||||
|
||||
/*! @brief Swap the buffers, then use the Wayland presentation-time protocol to
|
||||
* wait for the new frame to be presented. GLFW window events are processed for
|
||||
* the whole time this function waits for the frame to be presented.
|
||||
*
|
||||
* @return The presentation time of the frame, with respect to the same time
|
||||
* measure glfwGetTime() uses, or 0.0 if the frame was not shown due to a
|
||||
* vblank miss.
|
||||
*
|
||||
* @since Added in version 3.3.
|
||||
*
|
||||
* @ingroup native
|
||||
*/
|
||||
GLFWAPI double glfwWaylandSwapPres(GLFWwindow* window);
|
||||
#endif
|
||||
|
||||
#if defined(GLFW_EXPOSE_NATIVE_EGL)
|
||||
|
@ -55,6 +55,10 @@ elseif (_GLFW_WAYLAND)
|
||||
PROTOCOL
|
||||
"${WAYLAND_PROTOCOLS_PKGDATADIR}/unstable/idle-inhibit/idle-inhibit-unstable-v1.xml"
|
||||
BASENAME idle-inhibit-unstable-v1)
|
||||
ecm_add_wayland_client_protocol(glfw_SOURCES
|
||||
PROTOCOL
|
||||
"${WAYLAND_PROTOCOLS_PKGDATADIR}/stable/presentation-time/presentation-time.xml"
|
||||
BASENAME presentation-time)
|
||||
elseif (_GLFW_OSMESA)
|
||||
set(glfw_HEADERS ${common_HEADERS} null_platform.h null_joystick.h
|
||||
posix_time.h posix_thread.h osmesa_context.h)
|
||||
|
@ -777,12 +777,28 @@ static const struct xdg_wm_base_listener wmBaseListener = {
|
||||
wmBaseHandlePing
|
||||
};
|
||||
|
||||
static void
|
||||
presSetClockId(void *data, struct wp_presentation *pres, uint32_t clockId)
|
||||
{
|
||||
if (clockId == CLOCK_MONOTONIC)
|
||||
{
|
||||
// TODO: support for clocks other than CLOCK_MONOTONIC.
|
||||
_glfw.wl.pres = pres;
|
||||
}
|
||||
}
|
||||
|
||||
static const struct wp_presentation_listener presListener = {
|
||||
presSetClockId
|
||||
};
|
||||
|
||||
static void registryHandleGlobal(void* data,
|
||||
struct wl_registry* registry,
|
||||
uint32_t name,
|
||||
const char* interface,
|
||||
uint32_t version)
|
||||
{
|
||||
struct wp_presentation* pres;
|
||||
|
||||
if (strcmp(interface, "wl_compositor") == 0)
|
||||
{
|
||||
_glfw.wl.compositorVersion = min(3, version);
|
||||
@ -863,6 +879,13 @@ static void registryHandleGlobal(void* data,
|
||||
&zwp_idle_inhibit_manager_v1_interface,
|
||||
1);
|
||||
}
|
||||
else if (strcmp(interface, wp_presentation_interface.name) == 0)
|
||||
{
|
||||
pres = wl_registry_bind(registry, name,
|
||||
&wp_presentation_interface,
|
||||
1);
|
||||
wp_presentation_add_listener(pres, &presListener, NULL);
|
||||
}
|
||||
}
|
||||
|
||||
static void registryHandleGlobalRemove(void *data,
|
||||
|
@ -62,6 +62,7 @@ typedef VkBool32 (APIENTRY *PFN_vkGetPhysicalDeviceWaylandPresentationSupportKHR
|
||||
#include "wayland-relative-pointer-unstable-v1-client-protocol.h"
|
||||
#include "wayland-pointer-constraints-unstable-v1-client-protocol.h"
|
||||
#include "wayland-idle-inhibit-unstable-v1-client-protocol.h"
|
||||
#include "wayland-presentation-time-client-protocol.h"
|
||||
|
||||
#define _glfw_dlopen(name) dlopen(name, RTLD_LAZY | RTLD_LOCAL)
|
||||
#define _glfw_dlclose(handle) dlclose(handle)
|
||||
@ -216,6 +217,9 @@ typedef struct _GLFWwindowWayland
|
||||
int focus;
|
||||
} decorations;
|
||||
|
||||
GLFWbool presWaiting;
|
||||
double presTime;
|
||||
|
||||
} _GLFWwindowWayland;
|
||||
|
||||
// Wayland-specific global data
|
||||
@ -324,6 +328,8 @@ typedef struct _GLFWlibraryWayland
|
||||
PFN_wl_egl_window_resize window_resize;
|
||||
} egl;
|
||||
|
||||
struct wp_presentation* pres;
|
||||
|
||||
} _GLFWlibraryWayland;
|
||||
|
||||
// Wayland-specific per-monitor data
|
||||
|
@ -39,6 +39,7 @@
|
||||
#include <sys/mman.h>
|
||||
#include <sys/timerfd.h>
|
||||
#include <poll.h>
|
||||
#include <assert.h>
|
||||
|
||||
|
||||
static int createTmpfileCloexec(char* tmpname)
|
||||
@ -826,6 +827,13 @@ int _glfwPlatformCreateWindow(_GLFWwindow* window,
|
||||
window->wl.monitorsCount = 0;
|
||||
window->wl.monitorsSize = 1;
|
||||
|
||||
if (_glfw.wl.pres)
|
||||
{
|
||||
window->wl.presWaiting = GLFW_FALSE;
|
||||
// Tell the user we missed the first vblank.
|
||||
window->wl.presTime = 0.;
|
||||
}
|
||||
|
||||
return GLFW_TRUE;
|
||||
}
|
||||
|
||||
@ -1752,3 +1760,81 @@ GLFWAPI struct wl_surface* glfwGetWaylandWindow(GLFWwindow* handle)
|
||||
return window->wl.surface;
|
||||
}
|
||||
|
||||
|
||||
static void feedbackSyncOutput(void* data,
|
||||
struct wp_presentation_feedback* fback,
|
||||
struct wl_output* output)
|
||||
{
|
||||
}
|
||||
|
||||
static void feedbackPresented(void* data,
|
||||
struct wp_presentation_feedback* fback,
|
||||
uint32_t tvSecHi,
|
||||
uint32_t tvSecLo,
|
||||
uint32_t tvNsec,
|
||||
uint32_t refreshNsec,
|
||||
uint32_t seqHi,
|
||||
uint32_t seqLo,
|
||||
uint32_t flags)
|
||||
{
|
||||
_GLFWwindow* window;
|
||||
uint64_t sec;
|
||||
uint64_t nsec;
|
||||
|
||||
window = (_GLFWwindow*) data;
|
||||
|
||||
window->wl.presWaiting = GLFW_FALSE;
|
||||
|
||||
sec = (uint64_t) tvSecLo + ((uint64_t) tvSecHi << 32);
|
||||
nsec = sec * 1000000000 + (uint64_t) tvNsec;
|
||||
window->wl.presTime = (double) (nsec - _glfw.timer.offset) * 1e-9;
|
||||
|
||||
wp_presentation_feedback_destroy(fback);
|
||||
}
|
||||
|
||||
static void feedbackDiscarded(void* data,
|
||||
struct wp_presentation_feedback* fback)
|
||||
{
|
||||
_GLFWwindow* window = (_GLFWwindow*) data;
|
||||
window->wl.presWaiting = GLFW_FALSE;
|
||||
window->wl.presTime = 0.;
|
||||
|
||||
wp_presentation_feedback_destroy(fback);
|
||||
}
|
||||
|
||||
static const struct wp_presentation_feedback_listener feedbackListener = {
|
||||
feedbackSyncOutput,
|
||||
feedbackPresented,
|
||||
feedbackDiscarded
|
||||
};
|
||||
|
||||
GLFWAPI int glfwWaylandPresSupported(void)
|
||||
{
|
||||
_GLFW_REQUIRE_INIT_OR_RETURN(GLFW_FALSE);
|
||||
return _glfw.wl.pres != NULL;
|
||||
}
|
||||
|
||||
GLFWAPI double glfwWaylandSwapPres(GLFWwindow* handle)
|
||||
{
|
||||
_GLFWwindow* window;
|
||||
struct wp_presentation_feedback* fback;
|
||||
|
||||
_GLFW_REQUIRE_INIT_OR_RETURN(0.);
|
||||
assert(handle);
|
||||
assert(_glfw.wl.pres);
|
||||
|
||||
window = (_GLFWwindow*) handle;
|
||||
|
||||
glfwSwapBuffers(handle);
|
||||
|
||||
while (window->wl.presWaiting)
|
||||
{
|
||||
handleEvents(-1);
|
||||
}
|
||||
|
||||
window->wl.presWaiting = GLFW_TRUE;
|
||||
fback = wp_presentation_feedback(_glfw.wl.pres, window->wl.surface);
|
||||
wp_presentation_feedback_add_listener(fback, &feedbackListener, window);
|
||||
|
||||
return window->wl.presTime;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user