move test.h to libkmstest
[android/external-libkmsxx.git] / tests / 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"
10 #include "test.h"
12 using namespace std;
13 using namespace kms;
15 static void draw_color_bar(Framebuffer& buf, int old_xpos, int xpos, int width);
17 static void main_loop(Card& card);
19 class OutputFlipHandler
20 {
21 public:
22         OutputFlipHandler(Connector* conn, Crtc* crtc, Framebuffer* fb1, Framebuffer* fb2)
23                 : m_connector(conn), m_crtc(crtc), m_fbs { fb1, fb2 }, m_front_buf(1), m_bar_xpos(0)
24         {
25         }
27         ~OutputFlipHandler()
28         {
29                 delete m_fbs[0];
30                 delete m_fbs[1];
31         }
33         OutputFlipHandler(const OutputFlipHandler& other) = delete;
34         OutputFlipHandler& operator=(const OutputFlipHandler& other) = delete;
36         void set_mode()
37         {
38                 auto mode = m_connector->get_default_mode();
39                 int r = m_crtc->set_mode(m_connector, *m_fbs[0], mode);
40                 ASSERT(r == 0);
41         }
43         void handle_event()
44         {
45                 m_front_buf = (m_front_buf + 1) % 2;
47                 const int bar_width = 20;
48                 const int bar_speed = 8;
50                 auto crtc = m_crtc;
51                 auto fb = m_fbs[(m_front_buf + 1) % 2];
53                 ASSERT(crtc);
54                 ASSERT(fb);
56                 int current_xpos = m_bar_xpos;
57                 int old_xpos = (current_xpos + (fb->width() - bar_width - bar_speed)) % (fb->width() - bar_width);
58                 int new_xpos = (current_xpos + bar_speed) % (fb->width() - bar_width);
60                 draw_color_bar(*fb, old_xpos, new_xpos, bar_width);
62                 m_bar_xpos = new_xpos;
64                 auto& card = crtc->card();
66                 if (card.has_atomic()) {
67                         int r;
69                         AtomicReq ctx(card);
71                         ctx.add(m_crtc, card.get_prop("FB_ID"), fb->id());
73                         r = ctx.test();
74                         ASSERT(r == 0);
76                         r = ctx.commit(this);
77                         ASSERT(r == 0);
78                 } else {
79                         int r = crtc->page_flip(*fb, this);
80                         ASSERT(r == 0);
81                 }
82         }
84 private:
85         Connector* m_connector;
86         Crtc* m_crtc;
87         Framebuffer* m_fbs[2];
89         int m_front_buf;
90         int m_bar_xpos;
91 };
93 int main()
94 {
95         Card card;
97         if (card.master() == false)
98                 printf("Not DRM master, modeset may fail\n");
100         //card.print_short();
102         vector<OutputFlipHandler*> outputs;
104         for (auto pipe : card.get_connected_pipelines())
105         {
106                 auto conn = pipe.connector;
107                 auto crtc = pipe.crtc;
109                 auto mode = conn->get_default_mode();
111                 auto fb1 = new Framebuffer(card, mode.hdisplay, mode.vdisplay, "XR24");
112                 auto fb2 = new Framebuffer(card, mode.hdisplay, mode.vdisplay, "XR24");
114                 printf("conn %u, crtc %u, fb1 %u, fb2 %u\n", conn->id(), crtc->id(), fb1->id(), fb2->id());
116                 auto output = new OutputFlipHandler(conn, crtc, fb1, fb2);
117                 outputs.push_back(output);
118         }
120         for(auto out : outputs)
121                 out->set_mode();
123         for(auto out : outputs)
124                 out->handle_event();
126         main_loop(card);
128         for(auto out : outputs)
129                 delete out;
132 static void page_flip_handler(int fd, unsigned int frame,
133                               unsigned int sec, unsigned int usec,
134                               void *data)
136         //printf("flip event %d, %d, %u, %u, %p\n", fd, frame, sec, usec, data);
138         auto out = (OutputFlipHandler*)data;
140         out->handle_event();
144 static void main_loop(Card& card)
146         drmEventContext ev = {
147                 .version = DRM_EVENT_CONTEXT_VERSION,
148                 .vblank_handler = 0,
149                 .page_flip_handler = page_flip_handler,
150         };
152         fd_set fds;
154         FD_ZERO(&fds);
156         int fd = card.fd();
158         printf("press enter to exit\n");
160         while (true) {
161                 int r;
163                 FD_SET(0, &fds);
164                 FD_SET(fd, &fds);
166                 r = select(fd + 1, &fds, NULL, NULL, NULL);
167                 if (r < 0) {
168                         fprintf(stderr, "select() failed with %d: %m\n", errno);
169                         break;
170                 } else if (FD_ISSET(0, &fds)) {
171                         fprintf(stderr, "exit due to user-input\n");
172                         break;
173                 } else if (FD_ISSET(fd, &fds)) {
174                         drmHandleEvent(fd, &ev);
175                 }
176         }
180 static const RGB colors32[] = {
181         RGB(255, 255, 255),
182         RGB(255, 0, 0),
183         RGB(255, 255, 255),
184         RGB(0, 255, 0),
185         RGB(255, 255, 255),
186         RGB(0, 0, 255),
187         RGB(255, 255, 255),
188         RGB(200, 200, 200),
189         RGB(255, 255, 255),
190         RGB(100, 100, 100),
191         RGB(255, 255, 255),
192         RGB(50, 50, 50),
193 };
195 static const uint16_t colors16[] = {
196         colors32[0].rgb565(),
197         colors32[1].rgb565(),
198         colors32[2].rgb565(),
199         colors32[3].rgb565(),
200         colors32[4].rgb565(),
201         colors32[5].rgb565(),
202         colors32[6].rgb565(),
203         colors32[7].rgb565(),
204         colors32[8].rgb565(),
205         colors32[9].rgb565(),
206         colors32[10].rgb565(),
207         colors32[11].rgb565(),
208 };
210 static void drm_draw_color_bar_rgb888(Framebuffer& buf, int old_xpos, int xpos, int width)
212         for (unsigned y = 0; y < buf.height(); ++y) {
213                 RGB bcol = colors32[y * ARRAY_SIZE(colors32) / buf.height()];
214                 uint32_t *line = (uint32_t*)(buf.map(0) + buf.stride(0) * y);
216                 if (old_xpos >= 0) {
217                         for (int x = old_xpos; x < old_xpos + width; ++x)
218                                 line[x] = 0;
219                 }
221                 for (int x = xpos; x < xpos + width; ++x)
222                         line[x] = bcol.raw;
223         }
226 static void drm_draw_color_bar_rgb565(Framebuffer& buf, int old_xpos, int xpos, int width)
228         static_assert(ARRAY_SIZE(colors32) == ARRAY_SIZE(colors16), "bad colors arrays");
230         for (unsigned y = 0; y < buf.height(); ++y) {
231                 uint16_t bcol = colors16[y * ARRAY_SIZE(colors16) / buf.height()];
232                 uint16_t *line = (uint16_t*)(buf.map(0) + buf.stride(0) * y);
234                 if (old_xpos >= 0) {
235                         for (int x = old_xpos; x < old_xpos + width; ++x)
236                                 line[x] = 0;
237                 }
239                 for (int x = xpos; x < xpos + width; ++x)
240                         line[x] = bcol;
241         }
244 static void drm_draw_color_bar_semiplanar_yuv(Framebuffer& buf, int old_xpos, int xpos, int width)
246         const uint8_t colors[] = {
247                 0xff,
248                 0x00,
249                 0xff,
250                 0x20,
251                 0xff,
252                 0x40,
253                 0xff,
254                 0x80,
255                 0xff,
256         };
258         for (unsigned y = 0; y < buf.height(); ++y) {
259                 unsigned int bcol = colors[y * ARRAY_SIZE(colors) / buf.height()];
260                 uint8_t *line = (uint8_t*)(buf.map(0) + buf.stride(0) * y);
262                 if (old_xpos >= 0) {
263                         for (int x = old_xpos; x < old_xpos + width; ++x)
264                                 line[x] = 0;
265                 }
267                 for (int x = xpos; x < xpos + width; ++x)
268                         line[x] = bcol;
269         }
272 static void draw_color_bar(Framebuffer& buf, int old_xpos, int xpos, int width)
274         switch (buf.format()) {
275         case DRM_FORMAT_NV12:
276         case DRM_FORMAT_NV21:
277                 // XXX not right but gets something on the screen
278                 drm_draw_color_bar_semiplanar_yuv(buf, old_xpos, xpos, width);
279                 break;
281         case DRM_FORMAT_YUYV:
282         case DRM_FORMAT_UYVY:
283                 // XXX not right but gets something on the screen
284                 drm_draw_color_bar_rgb565(buf, old_xpos, xpos, width);
285                 break;
287         case DRM_FORMAT_RGB565:
288                 drm_draw_color_bar_rgb565(buf, old_xpos, xpos, width);
289                 break;
291         case DRM_FORMAT_XRGB8888:
292                 drm_draw_color_bar_rgb888(buf, old_xpos, xpos, width);
293                 break;
295         default:
296                 ASSERT(false);
297         }