testpat: fix printing of time
[android/external-libkmsxx.git] / db / db.cpp
1 #include <cstdio>
2 #include <algorithm>
4 #include <xf86drm.h>
5 #include <xf86drmMode.h>
6 #include <drm_fourcc.h>
8 #include "kms++.h"
9 #include "utils/color.h"
11 #include "../test.h"
13 using namespace std;
14 using namespace kms;
16 static void draw_color_bar(Framebuffer& buf, int old_xpos, int xpos, int width);
18 static void main_loop(Card& card);
20 #define ARRAY_SIZE(arr) (sizeof(arr) / sizeof((arr)[0]))
22 struct Output
23 {
24         Connector* connector;
25         Crtc* crtc;
26         Framebuffer* fbs[2];
28         int front_buf;
29         int bar_xpos;
30 };
32 static void do_flip(Output* out);
34 int main()
35 {
36         Card card;
38         if (card.master() == false)
39                 printf("Not DRM master, modeset may fail\n");
41         //card.print_short();
43         vector<Output> outputs;
45         for (auto conn : card.get_connectors())
46         {
47                 if (conn->connected() == false)
48                         continue;
50                 auto mode = conn->get_default_mode();
52                 Crtc* crtc = conn->get_current_crtc();
53                 if (!crtc) {
54                         for (auto c : conn->get_possible_crtcs()) {
55                                 if (find_if(outputs.begin(), outputs.end(), [c](Output o) { return o.crtc == c; }) == outputs.end()) {
56                                         crtc = c;
57                                         break;
58                                 }
59                         }
60                 }
62                 if (!crtc) {
63                         printf("failed to find crtc\n");
64                         return -1;
65                 }
67                 auto fb1 = new Framebuffer(card, mode.hdisplay, mode.vdisplay, "XR24");
68                 auto fb2 = new Framebuffer(card, mode.hdisplay, mode.vdisplay, "XR24");
70                 printf("conn %u, crtc %u, fb1 %u, fb2 %u\n", conn->id(), crtc->id(), fb1->id(), fb2->id());
72                 Output output = { };
73                 output.connector = conn;
74                 output.crtc = crtc;
75                 output.fbs[0] = fb1;
76                 output.fbs[1] = fb2;
77                 outputs.push_back(output);
78         }
80         for(auto& out : outputs) {
81                 auto conn = out.connector;
82                 auto crtc = out.crtc;
84                 auto mode = conn->get_default_mode();
85                 int r = crtc->set_mode(conn, *out.fbs[0], mode);
86                 ASSERT(r == 0);
87         }
89         for(auto& out : outputs)
90                 do_flip(&out);
92         main_loop(card);
94         for(auto& out : outputs) {
95                 delete out.fbs[0];
96                 delete out.fbs[1];
97         }
98 }
100 static void do_flip(Output* out)
102         const int bar_width = 20;
103         const int bar_speed = 8;
105         auto crtc = out->crtc;
106         auto fb = out->fbs[(out->front_buf + 1) % 2];
108         ASSERT(crtc);
109         ASSERT(fb);
111         int current_xpos = out->bar_xpos;
112         int old_xpos = (current_xpos + (fb->width() - bar_width - bar_speed)) % (fb->width() - bar_width);
113         int new_xpos = (current_xpos + bar_speed) % (fb->width() - bar_width);
115         draw_color_bar(*fb, old_xpos, new_xpos, bar_width);
117         out->bar_xpos = new_xpos;
119         auto& card = crtc->card();
121         if (card.has_atomic()) {
122                 int r;
124                 AtomicReq ctx(card);
126                 // XXX
127                 //ctx.add(plane, card.get_prop("CRTC_X"), 50);
128                 //ctx.add(plane, card.get_prop("CRTC_Y"), 50);
130                 r = ctx.test();
131                 ASSERT(r == 0);
133                 r = ctx.commit();
134                 ASSERT(r == 0);
135         } else {
136                 int r = drmModePageFlip(card.fd(), crtc->id(), fb->id(), DRM_MODE_PAGE_FLIP_EVENT, out);
137                 ASSERT(r == 0);
138         }
141 static void page_flip_handler(int fd, unsigned int frame,
142                               unsigned int sec, unsigned int usec,
143                               void *data)
145         //printf("flip event %d, %d, %u, %u, %p\n", fd, frame, sec, usec, data);
147         auto out = (Output*)data;
149         out->front_buf = (out->front_buf + 1) % 2;
151         do_flip(out);
155 static void main_loop(Card& card)
157         drmEventContext ev = {
158                 .version = DRM_EVENT_CONTEXT_VERSION,
159                 .vblank_handler = 0,
160                 .page_flip_handler = page_flip_handler,
161         };
163         fd_set fds;
165         FD_ZERO(&fds);
167         int fd = card.fd();
169         printf("press enter to exit\n");
171         while (true) {
172                 int r;
174                 FD_SET(0, &fds);
175                 FD_SET(fd, &fds);
177                 r = select(fd + 1, &fds, NULL, NULL, NULL);
178                 if (r < 0) {
179                         fprintf(stderr, "select() failed with %d: %m\n", errno);
180                         break;
181                 } else if (FD_ISSET(0, &fds)) {
182                         fprintf(stderr, "exit due to user-input\n");
183                         break;
184                 } else if (FD_ISSET(fd, &fds)) {
185                         drmHandleEvent(fd, &ev);
186                 }
187         }
191 static const RGB colors32[] = {
192         RGB(255, 255, 255),
193         RGB(255, 0, 0),
194         RGB(255, 255, 255),
195         RGB(0, 255, 0),
196         RGB(255, 255, 255),
197         RGB(0, 0, 255),
198         RGB(255, 255, 255),
199         RGB(200, 200, 200),
200         RGB(255, 255, 255),
201         RGB(100, 100, 100),
202         RGB(255, 255, 255),
203         RGB(50, 50, 50),
204 };
206 static const uint16_t colors16[] = {
207         colors32[0].rgb565(),
208         colors32[1].rgb565(),
209         colors32[2].rgb565(),
210         colors32[3].rgb565(),
211         colors32[4].rgb565(),
212         colors32[5].rgb565(),
213         colors32[6].rgb565(),
214         colors32[7].rgb565(),
215         colors32[8].rgb565(),
216         colors32[9].rgb565(),
217         colors32[10].rgb565(),
218         colors32[11].rgb565(),
219 };
221 static void drm_draw_color_bar_rgb888(Framebuffer& buf, int old_xpos, int xpos, int width)
223         for (unsigned y = 0; y < buf.height(); ++y) {
224                 RGB bcol = colors32[y * ARRAY_SIZE(colors32) / buf.height()];
225                 uint32_t *line = (uint32_t*)(buf.map(0) + buf.stride(0) * y);
227                 if (old_xpos >= 0) {
228                         for (int x = old_xpos; x < old_xpos + width; ++x)
229                                 line[x] = 0;
230                 }
232                 for (int x = xpos; x < xpos + width; ++x)
233                         line[x] = bcol.raw;
234         }
237 static void drm_draw_color_bar_rgb565(Framebuffer& buf, int old_xpos, int xpos, int width)
239         static_assert(ARRAY_SIZE(colors32) == ARRAY_SIZE(colors16), "bad colors arrays");
241         for (unsigned y = 0; y < buf.height(); ++y) {
242                 uint16_t bcol = colors16[y * ARRAY_SIZE(colors16) / buf.height()];
243                 uint16_t *line = (uint16_t*)(buf.map(0) + buf.stride(0) * y);
245                 if (old_xpos >= 0) {
246                         for (int x = old_xpos; x < old_xpos + width; ++x)
247                                 line[x] = 0;
248                 }
250                 for (int x = xpos; x < xpos + width; ++x)
251                         line[x] = bcol;
252         }
255 static void drm_draw_color_bar_semiplanar_yuv(Framebuffer& buf, int old_xpos, int xpos, int width)
257         const uint8_t colors[] = {
258                 0xff,
259                 0x00,
260                 0xff,
261                 0x20,
262                 0xff,
263                 0x40,
264                 0xff,
265                 0x80,
266                 0xff,
267         };
269         for (unsigned y = 0; y < buf.height(); ++y) {
270                 unsigned int bcol = colors[y * ARRAY_SIZE(colors) / buf.height()];
271                 uint8_t *line = (uint8_t*)(buf.map(0) + buf.stride(0) * y);
273                 if (old_xpos >= 0) {
274                         for (int x = old_xpos; x < old_xpos + width; ++x)
275                                 line[x] = 0;
276                 }
278                 for (int x = xpos; x < xpos + width; ++x)
279                         line[x] = bcol;
280         }
283 static void draw_color_bar(Framebuffer& buf, int old_xpos, int xpos, int width)
285         switch (buf.format()) {
286         case DRM_FORMAT_NV12:
287         case DRM_FORMAT_NV21:
288                 // XXX not right but gets something on the screen
289                 drm_draw_color_bar_semiplanar_yuv(buf, old_xpos, xpos, width);
290                 break;
292         case DRM_FORMAT_YUYV:
293         case DRM_FORMAT_UYVY:
294                 // XXX not right but gets something on the screen
295                 drm_draw_color_bar_rgb565(buf, old_xpos, xpos, width);
296                 break;
298         case DRM_FORMAT_RGB565:
299                 drm_draw_color_bar_rgb565(buf, old_xpos, xpos, width);
300                 break;
302         case DRM_FORMAT_XRGB8888:
303                 drm_draw_color_bar_rgb888(buf, old_xpos, xpos, width);
304                 break;
306         default:
307                 ASSERT(false);
308         }