TODO: remove YUV bug
[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 main_loop(Card& card);
17 class OutputFlipHandler : PageFlipHandlerBase
18 {
19 public:
20         OutputFlipHandler(Connector* conn, Crtc* crtc, DumbFramebuffer* fb1, DumbFramebuffer* fb2)
21                 : m_connector(conn), m_crtc(crtc), m_fbs { fb1, fb2 }, m_front_buf(1), m_bar_xpos(0)
22         {
23         }
25         ~OutputFlipHandler()
26         {
27                 delete m_fbs[0];
28                 delete m_fbs[1];
29         }
31         OutputFlipHandler(const OutputFlipHandler& other) = delete;
32         OutputFlipHandler& operator=(const OutputFlipHandler& other) = delete;
34         void set_mode()
35         {
36                 auto mode = m_connector->get_default_mode();
37                 int r = m_crtc->set_mode(m_connector, *m_fbs[0], mode);
38                 ASSERT(r == 0);
39         }
41         void handle_page_flip(uint32_t frame, double time)
42         {
43                 m_front_buf = (m_front_buf + 1) % 2;
45                 const int bar_width = 20;
46                 const int bar_speed = 8;
48                 auto crtc = m_crtc;
49                 auto fb = m_fbs[(m_front_buf + 1) % 2];
51                 ASSERT(crtc);
52                 ASSERT(fb);
54                 int current_xpos = m_bar_xpos;
55                 int old_xpos = (current_xpos + (fb->width() - bar_width - bar_speed)) % (fb->width() - bar_width);
56                 int new_xpos = (current_xpos + bar_speed) % (fb->width() - bar_width);
58                 draw_color_bar(*fb, old_xpos, new_xpos, bar_width);
60                 m_bar_xpos = new_xpos;
62                 auto& card = crtc->card();
64                 if (card.has_atomic()) {
65                         int r;
67                         AtomicReq req(card);
69                         req.add(m_crtc, "FB_ID", fb->id());
71                         r = req.test();
72                         ASSERT(r == 0);
74                         r = req.commit(this);
75                         ASSERT(r == 0);
76                 } else {
77                         int r = crtc->page_flip(*fb, this);
78                         ASSERT(r == 0);
79                 }
80         }
82 private:
83         Connector* m_connector;
84         Crtc* m_crtc;
85         DumbFramebuffer* m_fbs[2];
87         int m_front_buf;
88         int m_bar_xpos;
89 };
91 int main()
92 {
93         Card card;
95         if (card.master() == false)
96                 printf("Not DRM master, modeset may fail\n");
98         //card.print_short();
100         vector<OutputFlipHandler*> outputs;
102         for (auto pipe : card.get_connected_pipelines())
103         {
104                 auto conn = pipe.connector;
105                 auto crtc = pipe.crtc;
107                 auto mode = conn->get_default_mode();
109                 auto fb1 = new DumbFramebuffer(card, mode.hdisplay, mode.vdisplay, PixelFormat::XRGB8888);
110                 auto fb2 = new DumbFramebuffer(card, mode.hdisplay, mode.vdisplay, PixelFormat::XRGB8888);
112                 printf("conn %u, crtc %u, fb1 %u, fb2 %u\n", conn->id(), crtc->id(), fb1->id(), fb2->id());
114                 auto output = new OutputFlipHandler(conn, crtc, fb1, fb2);
115                 outputs.push_back(output);
116         }
118         for(auto out : outputs)
119                 out->set_mode();
121         for(auto out : outputs)
122                 out->handle_page_flip(0, 0);
124         main_loop(card);
126         for(auto out : outputs)
127                 delete out;
130 static void main_loop(Card& card)
132         fd_set fds;
134         FD_ZERO(&fds);
136         int fd = card.fd();
138         printf("press enter to exit\n");
140         while (true) {
141                 int r;
143                 FD_SET(0, &fds);
144                 FD_SET(fd, &fds);
146                 r = select(fd + 1, &fds, NULL, NULL, NULL);
147                 if (r < 0) {
148                         fprintf(stderr, "select() failed with %d: %m\n", errno);
149                         break;
150                 } else if (FD_ISSET(0, &fds)) {
151                         fprintf(stderr, "exit due to user-input\n");
152                         break;
153                 } else if (FD_ISSET(fd, &fds)) {
154                         card.call_page_flip_handlers();
155                 }
156         }