mirror of
https://github.com/brl/mutter.git
synced 2024-11-28 02:50:41 -05:00
wayland: Use timerfd for sub-msec poll() precision
Like the change to ClutterFrameClock, this allows poll() timeouts below 1 msec by using a timerfd which will trigger using G_POLL_IN. Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/3636>
This commit is contained in:
parent
0810238d22
commit
1513dd4ef7
@ -21,11 +21,18 @@
|
|||||||
|
|
||||||
#include "wayland/meta-wayland.h"
|
#include "wayland/meta-wayland.h"
|
||||||
|
|
||||||
|
#include <glib/gstdio.h>
|
||||||
|
|
||||||
#include <sys/time.h>
|
#include <sys/time.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <wayland-server.h>
|
#include <wayland-server.h>
|
||||||
|
|
||||||
|
#ifdef HAVE_TIMERFD
|
||||||
|
# include <sys/timerfd.h>
|
||||||
|
# include <time.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
#include "clutter/clutter.h"
|
#include "clutter/clutter.h"
|
||||||
#include "cogl/cogl-egl.h"
|
#include "cogl/cogl-egl.h"
|
||||||
#include "compositor/meta-surface-actor-wayland.h"
|
#include "compositor/meta-surface-actor-wayland.h"
|
||||||
@ -97,6 +104,11 @@ typedef struct
|
|||||||
|
|
||||||
MetaWaylandCompositor *compositor;
|
MetaWaylandCompositor *compositor;
|
||||||
ClutterStageView *stage_view;
|
ClutterStageView *stage_view;
|
||||||
|
|
||||||
|
#ifdef HAVE_TIMERFD
|
||||||
|
int tfd;
|
||||||
|
struct itimerspec tfd_spec;
|
||||||
|
#endif
|
||||||
} FrameCallbackSource;
|
} FrameCallbackSource;
|
||||||
|
|
||||||
static void meta_wayland_compositor_update_focus (MetaWaylandCompositor *compositor,
|
static void meta_wayland_compositor_update_focus (MetaWaylandCompositor *compositor,
|
||||||
@ -192,6 +204,50 @@ emit_frame_callbacks_for_stage_view (MetaWaylandCompositor *compositor,
|
|||||||
}
|
}
|
||||||
|
|
||||||
#ifdef HAVE_NATIVE_BACKEND
|
#ifdef HAVE_NATIVE_BACKEND
|
||||||
|
|
||||||
|
static gboolean
|
||||||
|
frame_callback_source_prepare (GSource *base,
|
||||||
|
int *timeout)
|
||||||
|
{
|
||||||
|
FrameCallbackSource *source = (FrameCallbackSource *)base;
|
||||||
|
|
||||||
|
*timeout = -1;
|
||||||
|
|
||||||
|
#ifdef HAVE_TIMERFD
|
||||||
|
if (source->tfd > -1)
|
||||||
|
{
|
||||||
|
int64_t ready_time = g_source_get_ready_time (base);
|
||||||
|
struct itimerspec tfd_spec;
|
||||||
|
|
||||||
|
tfd_spec.it_interval.tv_sec = 0;
|
||||||
|
tfd_spec.it_interval.tv_nsec = 0;
|
||||||
|
|
||||||
|
if (ready_time > -1)
|
||||||
|
{
|
||||||
|
tfd_spec.it_value.tv_sec = ready_time / G_USEC_PER_SEC;
|
||||||
|
tfd_spec.it_value.tv_nsec = (ready_time % G_USEC_PER_SEC) * 1000L;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
tfd_spec.it_value.tv_sec = 0;
|
||||||
|
tfd_spec.it_value.tv_nsec = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (memcmp (&tfd_spec, &source->tfd_spec, sizeof tfd_spec) != 0)
|
||||||
|
{
|
||||||
|
source->tfd_spec = tfd_spec;
|
||||||
|
|
||||||
|
timerfd_settime (source->tfd,
|
||||||
|
TFD_TIMER_ABSTIME,
|
||||||
|
&source->tfd_spec,
|
||||||
|
NULL);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
static gboolean
|
static gboolean
|
||||||
frame_callback_source_dispatch (GSource *source,
|
frame_callback_source_dispatch (GSource *source,
|
||||||
GSourceFunc callback,
|
GSourceFunc callback,
|
||||||
@ -214,9 +270,14 @@ frame_callback_source_finalize (GSource *source)
|
|||||||
|
|
||||||
g_signal_handlers_disconnect_by_data (frame_callback_source->stage_view,
|
g_signal_handlers_disconnect_by_data (frame_callback_source->stage_view,
|
||||||
source);
|
source);
|
||||||
|
|
||||||
|
#ifdef HAVE_TIMERFD
|
||||||
|
g_clear_fd (&frame_callback_source->tfd, NULL);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
static GSourceFuncs frame_callback_source_funcs = {
|
static GSourceFuncs frame_callback_source_funcs = {
|
||||||
|
.prepare = frame_callback_source_prepare,
|
||||||
.dispatch = frame_callback_source_dispatch,
|
.dispatch = frame_callback_source_dispatch,
|
||||||
.finalize = frame_callback_source_finalize,
|
.finalize = frame_callback_source_finalize,
|
||||||
};
|
};
|
||||||
@ -260,6 +321,13 @@ frame_callback_source_new (MetaWaylandCompositor *compositor,
|
|||||||
G_CALLBACK (on_stage_view_destroy),
|
G_CALLBACK (on_stage_view_destroy),
|
||||||
source);
|
source);
|
||||||
|
|
||||||
|
#ifdef HAVE_TIMERFD
|
||||||
|
frame_callback_source->tfd = timerfd_create (CLOCK_MONOTONIC, TFD_NONBLOCK | TFD_CLOEXEC);
|
||||||
|
|
||||||
|
if (frame_callback_source->tfd > -1)
|
||||||
|
g_source_add_unix_fd (source, frame_callback_source->tfd, G_IO_IN);
|
||||||
|
#endif
|
||||||
|
|
||||||
return &frame_callback_source->source;
|
return &frame_callback_source->source;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user