summaryrefslogtreecommitdiff
path: root/src/common_present.c
blob: 44b0427404e23b32db827f4e1157f69dc1a43f48 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif

#include <xf86drm.h>

#include "common_drm.h"
#include "common_drm_helper.h"

#include "present.h"

struct common_present_event {
	struct common_drm_event base;
	uint64_t event_id;
	struct xorg_list node;
};

static struct xorg_list events = { &events, &events };

static void common_present_handler(struct common_drm_event *base,
	uint64_t msc, unsigned int tv_sec, unsigned int tv_usec)
{
	struct common_present_event *event;

	event = container_of(base, struct common_present_event, base);

	if (!xorg_list_is_empty(&event->node)) {
		present_event_notify(event->event_id,
				     (uint64_t)tv_sec * 1000000 + tv_usec,
				     msc);

		xorg_list_del(&event->node);
	}
	free(event);
}

static RRCrtcPtr common_present_get_crtc(WindowPtr window)
{
	xf86CrtcPtr crtc = common_drm_drawable_covering_crtc(&window->drawable);

	return crtc ? crtc->randr_crtc : NULL;
}

static int common_present_get_ust_msc(RRCrtcPtr rr_crtc, uint64_t *ust,
	uint64_t *msc)
{
	xf86CrtcPtr crtc = rr_crtc->devPrivate;

	return common_drm_get_msc(crtc, ust, msc);
}

static Bool common_present_queue_vblank(RRCrtcPtr rr_crtc, uint64_t event_id,
	uint64_t msc)
{
	xf86CrtcPtr crtc = rr_crtc->devPrivate;
	struct common_present_event *event;
	int ret;

	event = calloc(1, sizeof *event);
	if (!event)
		return BadAlloc;

	event->base.crtc = crtc;
	event->base.handler = common_present_handler;
	event->event_id = event_id;

	ret = common_drm_queue_msc_event(crtc->scrn, crtc, &msc,
					 __FUNCTION__, FALSE, &event->base);
	if (ret == 0) {
		xorg_list_append(&event->node, &events);
		return Success;
	}

	free(event);

	return BadMatch; /* FIXME */
}

static void common_present_abort_vblank(RRCrtcPtr rr_crtc, uint64_t event_id,
	uint64_t msc)
{
	struct common_present_event *event;

	xorg_list_for_each_entry(event, &events, node) {
		if (event->event_id == event_id) {
			/*
			 * Cancel the event by taking it off the events list.
			 * We still expect DRM to trigger the event.
			 */
			xorg_list_del(&event->node);
			xorg_list_init(&event->node);
			break;
		}
	}
}

static void common_present_flush(WindowPtr window)
{
	/* Flush queued rendering - and wait for it? */
}

//static Bool common_present_check_flip(RRCrtcPtr crtc, WindowPtr window,
//	PixmapPtr pixmap, Bool sync_flip)
//{
//}

//static Bool common_present_flip(RRCrtcPtr crtc, uint64_t event_id,
//	uint64_t target_msc, PixmapPtr pixmap, Bool sync_flip)
//{
//}

//static void common_present_unflip(ScreenPtr screen, uint64_t event_id)
//{
//}

static present_screen_info_rec common_present_screen_info = {
	.version = PRESENT_SCREEN_INFO_VERSION,
	.get_crtc = common_present_get_crtc,
	.get_ust_msc = common_present_get_ust_msc,
	.queue_vblank = common_present_queue_vblank,
	.abort_vblank = common_present_abort_vblank,
	.flush = common_present_flush,
	.capabilities = PresentCapabilityNone,
//	.check_flip = common_present_check_flip,
//	.flip = common_present_flip,
//	.unflip = common_present_unflip,
};

Bool common_present_init(ScreenPtr pScreen)
{
	return present_screen_init(pScreen, &common_present_screen_info);
}