#include "libinput-seat.h"
#include "launcher-util.h"
#include "vaapi-recorder.h"
+#include "presentation_timing-server-protocol.h"
#ifndef DRM_CAP_TIMESTAMP_MONOTONIC
#define DRM_CAP_TIMESTAMP_MONOTONIC 0x6
finish_frame:
/* if we cannot page-flip, immediately finish frame */
clock_gettime(compositor->base.presentation_clock, &ts);
- weston_output_finish_frame(output_base, &ts);
+ weston_output_finish_frame(output_base, &ts,
+ PRESENTATION_FEEDBACK_INVALID);
}
static void
struct drm_sprite *s = (struct drm_sprite *)data;
struct drm_output *output = s->output;
struct timespec ts;
+ uint32_t flags = PRESENTATION_FEEDBACK_KIND_HW_COMPLETION |
+ PRESENTATION_FEEDBACK_KIND_HW_CLOCK;
drm_output_update_msc(output, frame);
output->vblank_pending = 0;
if (!output->page_flip_pending) {
ts.tv_sec = sec;
ts.tv_nsec = usec * 1000;
- weston_output_finish_frame(&output->base, &ts);
+ weston_output_finish_frame(&output->base, &ts, flags);
}
}
{
struct drm_output *output = (struct drm_output *) data;
struct timespec ts;
+ uint32_t flags = PRESENTATION_FEEDBACK_KIND_VSYNC |
+ PRESENTATION_FEEDBACK_KIND_HW_COMPLETION |
+ PRESENTATION_FEEDBACK_KIND_HW_CLOCK;
drm_output_update_msc(output, frame);
else if (!output->vblank_pending) {
ts.tv_sec = sec;
ts.tv_nsec = usec * 1000;
- weston_output_finish_frame(&output->base, &ts);
+ weston_output_finish_frame(&output->base, &ts, flags);
/* We can't call this from frame_notify, because the output's
* repaint needed flag is cleared just after that */
#include "pixman-renderer.h"
#include "libinput-seat.h"
#include "gl-renderer.h"
+#include "presentation_timing-server-protocol.h"
struct fbdev_compositor {
struct weston_compositor base;
struct timespec ts;
clock_gettime(output->compositor->presentation_clock, &ts);
- weston_output_finish_frame(output, &ts);
+ weston_output_finish_frame(output, &ts, PRESENTATION_FEEDBACK_INVALID);
}
static void
finish_frame_handler(void *data)
{
struct fbdev_output *output = data;
+ struct timespec ts;
- fbdev_output_start_repaint_loop(&output->base);
+ clock_gettime(output->base.compositor->presentation_clock, &ts);
+ weston_output_finish_frame(&output->base, &ts, 0);
return 1;
}
#include "compositor.h"
#include "pixman-renderer.h"
+#include "presentation_timing-server-protocol.h"
struct headless_compositor {
struct weston_compositor base;
struct timespec ts;
clock_gettime(output->compositor->presentation_clock, &ts);
- weston_output_finish_frame(output, &ts);
+ weston_output_finish_frame(output, &ts, PRESENTATION_FEEDBACK_INVALID);
}
static int
finish_frame_handler(void *data)
{
- headless_output_start_repaint_loop(data);
+ struct headless_output *output = data;
+ struct timespec ts;
+
+ clock_gettime(output->base.compositor->presentation_clock, &ts);
+ weston_output_finish_frame(&output->base, &ts, 0);
return 1;
}
struct timespec ts;
clock_gettime(output->compositor->presentation_clock, &ts);
- weston_output_finish_frame(output, &ts);
+ weston_output_finish_frame(output, &ts, PRESENTATION_FEEDBACK_INVALID);
}
static int
static int
finish_frame_handler(void *data)
{
- rdp_output_start_repaint_loop(data);
+ struct rdp_output *output = data;
+ struct timespec ts;
+
+ clock_gettime(output->base.compositor->presentation_clock, &ts);
+ weston_output_finish_frame(&output->base, &ts, 0);
return 1;
}
#include "rpi-renderer.h"
#include "launcher-util.h"
#include "libinput-seat.h"
+#include "presentation_timing-server-protocol.h"
#if 0
#define DBG(...) \
{
struct timespec ts;
+ /* XXX: do a phony dispmanx update and trigger on its completion? */
clock_gettime(output->compositor->presentation_clock, &ts);
- weston_output_finish_frame(output, &ts);
+ weston_output_finish_frame(output, &ts, PRESENTATION_FEEDBACK_INVALID);
}
static int
rpi_output_update_complete(struct rpi_output *output,
const struct timespec *stamp)
{
+ uint32_t flags = PRESENTATION_FEEDBACK_KIND_VSYNC |
+ PRESENTATION_FEEDBACK_KIND_HW_COMPLETION;
+
DBG("frame update complete(%ld.%09ld)\n",
(long)stamp->tv_sec, (long)stamp->tv_nsec);
rpi_renderer_finish_frame(&output->base);
- weston_output_finish_frame(&output->base, stamp);
+ weston_output_finish_frame(&output->base, stamp, flags);
}
static void
#include "../shared/os-compatibility.h"
#include "../shared/cairo-util.h"
#include "fullscreen-shell-client-protocol.h"
+#include "presentation_timing-server-protocol.h"
#define WINDOW_TITLE "Weston Compositor"
/* XXX: use the presentation extension for proper timings */
ts.tv_sec = time / 1000;
ts.tv_nsec = (time % 1000) * 1000000;
- weston_output_finish_frame(output, &ts);
+ weston_output_finish_frame(output, &ts, 0);
}
static const struct wl_callback_listener frame_listener = {
#include "pixman-renderer.h"
#include "../shared/config-parser.h"
#include "../shared/image-loader.h"
+#include "presentation_timing-server-protocol.h"
#define DEFAULT_AXIS_STEP_DISTANCE wl_fixed_from_int(10)
struct timespec ts;
clock_gettime(output->compositor->presentation_clock, &ts);
- weston_output_finish_frame(output, &ts);
+ weston_output_finish_frame(output, &ts, PRESENTATION_FEEDBACK_INVALID);
}
static int
finish_frame_handler(void *data)
{
struct x11_output *output = data;
+ struct timespec ts;
- x11_output_start_repaint_loop(&output->base);
+ clock_gettime(output->base.compositor->presentation_clock, &ts);
+ weston_output_finish_frame(&output->base, &ts, 0);
return 1;
}
struct weston_output *output,
uint32_t refresh_nsec,
const struct timespec *ts,
- uint64_t seq)
+ uint64_t seq,
+ uint32_t flags)
{
struct wl_client *client = wl_resource_get_client(feedback->resource);
struct wl_resource *o;
uint64_t secs;
- uint32_t flags = 0;
wl_resource_for_each(o, &output->resource_list) {
if (wl_resource_get_client(o) != client)
struct weston_output *output,
uint32_t refresh_nsec,
const struct timespec *ts,
- uint64_t seq)
+ uint64_t seq,
+ uint32_t flags)
{
struct weston_presentation_feedback *feedback, *tmp;
+ assert(!(flags & PRESENTATION_FEEDBACK_INVALID) ||
+ wl_list_empty(list));
+
wl_list_for_each_safe(feedback, tmp, list, link)
weston_presentation_feedback_present(feedback, output,
- refresh_nsec, ts, seq);
+ refresh_nsec, ts, seq,
+ flags);
}
static void
WL_EXPORT void
weston_output_finish_frame(struct weston_output *output,
- const struct timespec *stamp)
+ const struct timespec *stamp,
+ uint32_t presented_flags)
{
struct weston_compositor *compositor = output->compositor;
struct wl_event_loop *loop =
refresh_nsec = 1000000000000UL / output->current_mode->refresh;
weston_presentation_feedback_present_list(&output->feedback_list,
output, refresh_nsec, stamp,
- output->msc);
+ output->msc,
+ presented_flags);
output->frame_time = stamp->tv_sec * 1000 + stamp->tv_nsec / 1000000;
struct weston_plane *plane,
struct weston_plane *above);
+/* An invalid flag in presented_flags to catch logic errors. */
+#define PRESENTATION_FEEDBACK_INVALID (1U << 31)
+
void
weston_output_finish_frame(struct weston_output *output,
- const struct timespec *stamp);
+ const struct timespec *stamp,
+ uint32_t presented_flags);
void
weston_output_schedule_repaint(struct weston_output *output);
void