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