1#include <stdio.h>
2#include <stdlib.h>
3#include <sys/types.h>
4#include <sys/stat.h>
5#include <sys/select.h>
6#include <fcntl.h>
7#include <unistd.h>
8#include <string.h>
9#include <signal.h>
10#include <time.h>
11#include <errno.h>
12
13#include <xf86drm.h>
14
15#include "dev.h"
16#include "bo.h"
17#include "modeset.h"
18
19static int terminate = 0;
20
21static void sigint_handler(int arg)
22{
23	terminate = 1;
24}
25
26static void
27page_flip_handler(int fd, unsigned int sequence, unsigned int tv_sec,
28		unsigned int tv_usec, void *user_data)
29{
30}
31
32static void incrementor(int *inc, int *val, int increment, int lower, int upper)
33{
34	if(*inc > 0)
35		*inc = *val + increment >= upper ? -1 : 1;
36	else
37		*inc = *val - increment <= lower ? 1 : -1;
38	*val += *inc * increment;
39}
40
41int main(int argc, char *argv[])
42{
43	int ret, i, j, num_test_planes;
44	int x_inc = 1, x = 0, y_inc = 1, y = 0;
45	uint32_t plane_w = 128, plane_h = 128;
46	struct sp_dev *dev;
47	struct sp_plane **plane = NULL;
48	struct sp_crtc *test_crtc;
49	fd_set fds;
50	drmModePropertySetPtr pset;
51	drmEventContext event_context = {
52		.version = DRM_EVENT_CONTEXT_VERSION,
53		.page_flip_handler = page_flip_handler,
54	};
55	int card = 0, crtc = 0;
56
57	signal(SIGINT, sigint_handler);
58
59	parse_arguments(argc, argv, &card, &crtc);
60
61	dev = create_sp_dev(card);
62	if (!dev) {
63		printf("Failed to create sp_dev\n");
64		return -1;
65	}
66
67	if (crtc >= dev->num_crtcs) {
68		printf("Invalid crtc %d (num=%d)\n", crtc, dev->num_crtcs);
69		return -1;
70	}
71
72	ret = initialize_screens(dev);
73	if (ret) {
74		printf("Failed to initialize screens\n");
75		goto out;
76	}
77	test_crtc = &dev->crtcs[crtc];
78
79	plane = calloc(dev->num_planes, sizeof(*plane));
80	if (!plane) {
81		printf("Failed to allocate plane array\n");
82		goto out;
83	}
84
85	/* Create our planes */
86	num_test_planes = test_crtc->num_planes;
87	for (i = 0; i < num_test_planes; i++) {
88		plane[i] = get_sp_plane(dev, test_crtc);
89		if (!plane[i]) {
90			printf("no unused planes available\n");
91			goto out;
92		}
93
94		plane[i]->bo = create_sp_bo(dev, plane_w, plane_h, 16, plane[i]->format, 0);
95		if (!plane[i]->bo) {
96			printf("failed to create plane bo\n");
97			goto out;
98		}
99
100		fill_bo(plane[i]->bo, 0xFF, 0xFF, 0xFF, 0xFF);
101	}
102
103	pset = drmModePropertySetAlloc();
104	if (!pset) {
105		printf("Failed to allocate the property set\n");
106		goto out;
107	}
108
109	while (!terminate) {
110		FD_ZERO(&fds);
111		FD_SET(dev->fd, &fds);
112
113		incrementor(&x_inc, &x, 5, 0,
114			test_crtc->crtc->mode.hdisplay - plane_w);
115		incrementor(&y_inc, &y, 5, 0, test_crtc->crtc->mode.vdisplay -
116						plane_h * num_test_planes);
117
118		for (j = 0; j < num_test_planes; j++) {
119			ret = set_sp_plane_pset(dev, plane[j], pset, test_crtc,
120					x, y + j * plane_h);
121			if (ret) {
122				printf("failed to move plane %d\n", ret);
123				goto out;
124			}
125		}
126
127		ret = drmModePropertySetCommit(dev->fd,
128				DRM_MODE_PAGE_FLIP_EVENT, NULL, pset);
129		if (ret) {
130			printf("failed to commit properties ret=%d\n", ret);
131			goto out;
132		}
133
134		do {
135			ret = select(dev->fd + 1, &fds, NULL, NULL, NULL);
136		} while (ret == -1 && errno == EINTR);
137
138		if (FD_ISSET(dev->fd, &fds))
139			drmHandleEvent(dev->fd, &event_context);
140	}
141
142	drmModePropertySetFree(pset);
143
144	for (i = 0; i < num_test_planes; i++)
145		put_sp_plane(plane[i]);
146
147out:
148	destroy_sp_dev(dev);
149	free(plane);
150	return ret;
151}
152