take two
[profile/ivi/xorg-x11-drv-intel.git] / test / dri2-swap.c
1 #include <stdint.h>
2 #include <stdio.h>
3 #include <stdlib.h>
4
5 #include <X11/Xlib.h>
6 #include <X11/Xutil.h>
7 #include <X11/extensions/Xfixes.h>
8 #include <unistd.h>
9 #include <fcntl.h>
10 #include <string.h>
11 #include <time.h>
12
13 #include <xf86drm.h>
14 #include <drm.h>
15
16 #include "dri2.h"
17
18 #define COUNT 60
19
20 static int dri2_open(Display *dpy)
21 {
22         drm_auth_t auth;
23         char *driver, *device;
24         int fd;
25
26         if (!DRI2Connect(dpy, DefaultRootWindow(dpy), &driver, &device))
27                 return -1;
28
29         printf ("Connecting to %s driver on %s\n", driver, device);
30
31         fd = open("/dev/dri/card0", O_RDWR);
32         if (fd < 0)
33                 return -1;
34
35         if (drmIoctl(fd, DRM_IOCTL_GET_MAGIC, &auth))
36                 return -1;
37
38         if (!DRI2Authenticate(dpy, DefaultRootWindow(dpy), auth.magic))
39                 return -1;
40
41         return fd;
42 }
43
44 static void dri2_copy_swap(Display *dpy, Drawable d,
45                            int width, int height, int has_front)
46 {
47         XRectangle rect;
48         XserverRegion region;
49
50         rect.x = 0;
51         rect.y = 0;
52         rect.width = width;
53         rect.height = height;
54
55         region = XFixesCreateRegion(dpy, &rect, 1);
56         DRI2CopyRegion(dpy, d, region, DRI2BufferFrontLeft, DRI2BufferBackLeft);
57         if (has_front)
58                 DRI2CopyRegion(dpy, d, region, DRI2BufferFakeFrontLeft, DRI2BufferFrontLeft);
59         XFixesDestroyRegion(dpy, region);
60 }
61
62 static void xsync(Display *dpy, Window win)
63 {
64         XImage *image;
65
66         image = XGetImage(dpy, win, 0, 0, 1, 1, ~0, ZPixmap);
67         if (image)
68                 XDestroyImage(image);
69 }
70
71 static double elapsed(const struct timespec *start,
72                       const struct timespec *end)
73 {
74         return (end->tv_sec - start->tv_sec) +
75                 1e-9*(end->tv_nsec - start->tv_nsec);
76 }
77
78 static void run(Display *dpy, int width, int height,
79                 unsigned int *attachments, int nattachments,
80                 const char *name)
81 {
82         Window win;
83         XSetWindowAttributes attr;
84         int count;
85         DRI2Buffer *buffers;
86         struct timespec start, end;
87
88         /* Be nasty and install a fullscreen window on top so that we
89          * can guarantee we do not get clipped by children.
90          */
91         attr.override_redirect = 1;
92         win = XCreateWindow(dpy, DefaultRootWindow(dpy),
93                          0, 0, width, height, 0,
94                          DefaultDepth(dpy, DefaultScreen(dpy)),
95                          InputOutput,
96                          DefaultVisual(dpy, DefaultScreen(dpy)),
97                          CWOverrideRedirect, &attr);
98         XMapWindow(dpy, win);
99         xsync(dpy, win);
100
101         DRI2CreateDrawable(dpy, win);
102
103         buffers = DRI2GetBuffers(dpy, win, &width, &height,
104                                  attachments, nattachments, &count);
105         if (count != nattachments)
106                 return;
107
108         xsync(dpy, win);
109         clock_gettime(CLOCK_MONOTONIC, &start);
110         for (count = 0; count < COUNT; count++)
111                 DRI2SwapBuffers(dpy, win, 0, 0, 0);
112         xsync(dpy, win);
113         clock_gettime(CLOCK_MONOTONIC, &end);
114         printf("%d %s (%dx%d) swaps in %fs.\n",
115                count, name, width, height, elapsed(&start, &end));
116
117         xsync(dpy, win);
118         clock_gettime(CLOCK_MONOTONIC, &start);
119         for (count = 0; count < COUNT; count++)
120                 dri2_copy_swap(dpy, win, width, height, nattachments == 2);
121         xsync(dpy, win);
122         clock_gettime(CLOCK_MONOTONIC, &end);
123
124         printf("%d %s (%dx%d) blits in %fs.\n",
125                count, name, width, height, elapsed(&start, &end));
126
127         DRI2SwapInterval(dpy, win, 0);
128
129         xsync(dpy, win);
130         clock_gettime(CLOCK_MONOTONIC, &start);
131         for (count = 0; count < COUNT; count++)
132                 DRI2SwapBuffers(dpy, win, 0, 0, 0);
133         xsync(dpy, win);
134         clock_gettime(CLOCK_MONOTONIC, &end);
135         printf("%d %s (%dx%d) vblank=0 swaps in %fs.\n",
136                count, name, width, height, elapsed(&start, &end));
137
138         XDestroyWindow(dpy, win);
139         free(buffers);
140
141         XSync(dpy, 1);
142 }
143
144 int main(void)
145 {
146         Display *dpy;
147         int width, height, fd;
148         unsigned int attachments[] = {
149                 DRI2BufferBackLeft,
150                 DRI2BufferFrontLeft,
151         };
152
153         dpy = XOpenDisplay (NULL);
154         if (dpy == NULL)
155                 return 77;
156
157         fd = dri2_open(dpy);
158         if (fd < 0)
159                 return 1;
160
161         width = WidthOfScreen(DefaultScreenOfDisplay(dpy));
162         height = HeightOfScreen(DefaultScreenOfDisplay(dpy));
163         run(dpy, width, height, attachments, 1, "fullscreen");
164         run(dpy, width, height, attachments, 2, "fullscreen (with front)");
165
166         width /= 2;
167         height /= 2;
168         run(dpy, width, height, attachments, 1, "windowed");
169         run(dpy, width, height, attachments, 2, "windowed (with front)");
170
171         return 0;
172 }