]> Gitweb @ Texas Instruments - Open Source Git Repositories - git.TI.com/gitweb - android/external-libkmsxx.git/blobdiff - tests/db.cpp
db: print slowest frame time
[android/external-libkmsxx.git] / tests / db.cpp
index 5df104d87a93c5a2e2b0890dc06831350b6dcc0b..4a7846cb5ce47d1bbe0b6a645190830fe5f50ccf 100644 (file)
 #include <cstdio>
 #include <algorithm>
+#include <chrono>
 
 #include <xf86drm.h>
 #include <xf86drmMode.h>
 #include <drm_fourcc.h>
 
 #include "kms++.h"
-#include "utils/color.h"
 
 #include "test.h"
 
 using namespace std;
 using namespace kms;
 
-static void draw_color_bar(Framebuffer& buf, int old_xpos, int xpos, int width);
-
 static void main_loop(Card& card);
 
-#define ARRAY_SIZE(arr) (sizeof(arr) / sizeof((arr)[0]))
-
-class OutputFlipHandler
+class Flipper
 {
 public:
-       OutputFlipHandler(Connector* conn, Crtc* crtc, Framebuffer* fb1, Framebuffer* fb2)
-               : m_connector(conn), m_crtc(crtc), m_fbs { fb1, fb2 }, m_front_buf(1), m_bar_xpos(0)
+       Flipper(Card& card, unsigned width, unsigned height)
+               : m_current(0), m_bar_xpos(0)
        {
+               auto format = PixelFormat::XRGB8888;
+               m_fbs[0] = new DumbFramebuffer(card, width, height, format);
+               m_fbs[1] = new DumbFramebuffer(card, width, height, format);
        }
 
-       ~OutputFlipHandler()
+       ~Flipper()
        {
                delete m_fbs[0];
                delete m_fbs[1];
        }
 
+       Framebuffer* get_next()
+       {
+               m_current ^= 1;
+
+               const int bar_width = 20;
+               const int bar_speed = 8;
+
+               auto fb = m_fbs[m_current];
+
+               int current_xpos = m_bar_xpos;
+               int old_xpos = (current_xpos + (fb->width() - bar_width - bar_speed)) % (fb->width() - bar_width);
+               int new_xpos = (current_xpos + bar_speed) % (fb->width() - bar_width);
+
+               draw_color_bar(*fb, old_xpos, new_xpos, bar_width);
+
+               m_bar_xpos = new_xpos;
+
+               return fb;
+       }
+
+private:
+       DumbFramebuffer* m_fbs[2];
+
+       int m_current;
+       int m_bar_xpos;
+};
+
+class OutputFlipHandler : private PageFlipHandlerBase
+{
+public:
+       OutputFlipHandler(Connector* conn, Crtc* crtc, const Videomode& mode)
+               : m_connector(conn), m_crtc(crtc), m_mode(mode),
+                 m_flipper(conn->card(), mode.hdisplay, mode.vdisplay),
+                 m_plane(0), m_plane_flipper(0)
+       {
+       }
+
+       OutputFlipHandler(Connector* conn, Crtc* crtc, const Videomode& mode,
+                         Plane* plane, unsigned pwidth, unsigned pheight)
+               : m_connector(conn), m_crtc(crtc), m_mode(mode),
+                 m_flipper(conn->card(), mode.hdisplay, mode.vdisplay),
+                 m_plane(plane)
+       {
+               m_plane_flipper = new Flipper(conn->card(), pwidth, pheight);
+       }
+
+       ~OutputFlipHandler()
+       {
+               if (m_plane_flipper)
+                       delete m_plane_flipper;
+       }
+
        OutputFlipHandler(const OutputFlipHandler& other) = delete;
        OutputFlipHandler& operator=(const OutputFlipHandler& other) = delete;
 
        void set_mode()
        {
                auto mode = m_connector->get_default_mode();
-               int r = m_crtc->set_mode(m_connector, *m_fbs[0], mode);
+               auto fb = m_flipper.get_next();
+               int r = m_crtc->set_mode(m_connector, *fb, mode);
                ASSERT(r == 0);
+
+               if (m_plane) {
+                       auto planefb = m_plane_flipper->get_next();
+                       r = m_crtc->set_plane(m_plane, *planefb,
+                                             0, 0, planefb->width(), planefb->height(),
+                                             0, 0, planefb->width(), planefb->height());
+                       ASSERT(r == 0);
+               }
        }
 
-       void handle_event()
+       void start_flipping()
        {
-               m_front_buf = (m_front_buf + 1) % 2;
+               m_time_last = m_t1 = std::chrono::steady_clock::now();
+               m_slowest_frame = std::chrono::duration<float>::min();
+               m_frame_num = 0;
+               queue_next();
+       }
 
-               const int bar_width = 20;
-               const int bar_speed = 8;
+private:
+       void handle_page_flip(uint32_t frame, double time)
+       {
+               ++m_frame_num;
 
-               auto crtc = m_crtc;
-               auto fb = m_fbs[(m_front_buf + 1) % 2];
+               auto now = std::chrono::steady_clock::now();
 
-               ASSERT(crtc);
-               ASSERT(fb);
+               std::chrono::duration<float> diff = now - m_time_last;
+               if (diff > m_slowest_frame)
+                       m_slowest_frame = diff;
 
-               int current_xpos = m_bar_xpos;
-               int old_xpos = (current_xpos + (fb->width() - bar_width - bar_speed)) % (fb->width() - bar_width);
-               int new_xpos = (current_xpos + bar_speed) % (fb->width() - bar_width);
+               if (m_frame_num  % 100 == 0) {
+                       std::chrono::duration<float> fsec = now - m_t1;
+                       printf("Output %d: fps %f, slowest %.2f ms\n",
+                              m_connector->idx(), 100.0 / fsec.count(),
+                              m_slowest_frame.count() * 1000);
+                       m_t1 = now;
+                       m_slowest_frame = std::chrono::duration<float>::min();
+               }
 
-               draw_color_bar(*fb, old_xpos, new_xpos, bar_width);
+               m_time_last = now;
 
-               m_bar_xpos = new_xpos;
+               queue_next();
+       }
 
+       void queue_next()
+       {
+               auto crtc = m_crtc;
                auto& card = crtc->card();
 
+               auto fb = m_flipper.get_next();
+               Framebuffer* planefb = m_plane ? m_plane_flipper->get_next() : 0;
+
                if (card.has_atomic()) {
                        int r;
 
-                       AtomicReq ctx(card);
+                       AtomicReq req(card);
 
-                       ctx.add(m_crtc, card.get_prop("FB_ID"), fb->id());
+                       req.add(m_crtc, "FB_ID", fb->id());
+                       if (m_plane)
+                               req.add(m_plane, "FB_ID", planefb->id());
 
-                       r = ctx.test();
+                       r = req.test();
                        ASSERT(r == 0);
 
-                       r = ctx.commit(this);
+                       r = req.commit(this);
                        ASSERT(r == 0);
                } else {
-                       int r = drmModePageFlip(card.fd(), m_crtc->id(), fb->id(), DRM_MODE_PAGE_FLIP_EVENT, this);
+                       int r = crtc->page_flip(*fb, this);
                        ASSERT(r == 0);
+
+                       if (m_plane) {
+                               r = m_crtc->set_plane(m_plane, *planefb,
+                                                     0, 0, planefb->width(), planefb->height(),
+                                                     0, 0, planefb->width(), planefb->height());
+                               ASSERT(r == 0);
+                       }
                }
        }
 
 private:
        Connector* m_connector;
        Crtc* m_crtc;
-       Framebuffer* m_fbs[2];
+       Videomode m_mode;
 
-       int m_front_buf;
-       int m_bar_xpos;
+       int m_frame_num;
+       chrono::steady_clock::time_point m_t1;
+       chrono::steady_clock::time_point m_time_last;
+       chrono::duration<float> m_slowest_frame;
+
+       Flipper m_flipper;
+
+       Plane* m_plane;
+       Flipper* m_plane_flipper;
 };
 
 int main()
@@ -100,23 +194,29 @@ int main()
        if (card.master() == false)
                printf("Not DRM master, modeset may fail\n");
 
-       //card.print_short();
-
        vector<OutputFlipHandler*> outputs;
 
        for (auto pipe : card.get_connected_pipelines())
        {
                auto conn = pipe.connector;
                auto crtc = pipe.crtc;
-
                auto mode = conn->get_default_mode();
 
-               auto fb1 = new Framebuffer(card, mode.hdisplay, mode.vdisplay, "XR24");
-               auto fb2 = new Framebuffer(card, mode.hdisplay, mode.vdisplay, "XR24");
-
-               printf("conn %u, crtc %u, fb1 %u, fb2 %u\n", conn->id(), crtc->id(), fb1->id(), fb2->id());
 
-               auto output = new OutputFlipHandler(conn, crtc, fb1, fb2);
+               Plane* plane = 0;
+#if 0 // disable the plane for now
+               for (Plane* p : crtc->get_possible_planes()) {
+                       if (p->plane_type() == PlaneType::Overlay) {
+                               plane = p;
+                               break;
+                       }
+               }
+#endif
+               OutputFlipHandler* output;
+               if (plane)
+                       output = new OutputFlipHandler(conn, crtc, mode, plane, 500, 400);
+               else
+                       output = new OutputFlipHandler(conn, crtc, mode);
                outputs.push_back(output);
        }
 
@@ -124,7 +224,7 @@ int main()
                out->set_mode();
 
        for(auto out : outputs)
-               out->handle_event();
+               out->start_flipping();
 
        main_loop(card);
 
@@ -132,26 +232,8 @@ int main()
                delete out;
 }
 
-static void page_flip_handler(int fd, unsigned int frame,
-                             unsigned int sec, unsigned int usec,
-                             void *data)
-{
-       //printf("flip event %d, %d, %u, %u, %p\n", fd, frame, sec, usec, data);
-
-       auto out = (OutputFlipHandler*)data;
-
-       out->handle_event();
-}
-
-
 static void main_loop(Card& card)
 {
-       drmEventContext ev = {
-               .version = DRM_EVENT_CONTEXT_VERSION,
-               .vblank_handler = 0,
-               .page_flip_handler = page_flip_handler,
-       };
-
        fd_set fds;
 
        FD_ZERO(&fds);
@@ -174,128 +256,7 @@ static void main_loop(Card& card)
                        fprintf(stderr, "exit due to user-input\n");
                        break;
                } else if (FD_ISSET(fd, &fds)) {
-                       drmHandleEvent(fd, &ev);
-               }
-       }
-}
-
-
-static const RGB colors32[] = {
-       RGB(255, 255, 255),
-       RGB(255, 0, 0),
-       RGB(255, 255, 255),
-       RGB(0, 255, 0),
-       RGB(255, 255, 255),
-       RGB(0, 0, 255),
-       RGB(255, 255, 255),
-       RGB(200, 200, 200),
-       RGB(255, 255, 255),
-       RGB(100, 100, 100),
-       RGB(255, 255, 255),
-       RGB(50, 50, 50),
-};
-
-static const uint16_t colors16[] = {
-       colors32[0].rgb565(),
-       colors32[1].rgb565(),
-       colors32[2].rgb565(),
-       colors32[3].rgb565(),
-       colors32[4].rgb565(),
-       colors32[5].rgb565(),
-       colors32[6].rgb565(),
-       colors32[7].rgb565(),
-       colors32[8].rgb565(),
-       colors32[9].rgb565(),
-       colors32[10].rgb565(),
-       colors32[11].rgb565(),
-};
-
-static void drm_draw_color_bar_rgb888(Framebuffer& buf, int old_xpos, int xpos, int width)
-{
-       for (unsigned y = 0; y < buf.height(); ++y) {
-               RGB bcol = colors32[y * ARRAY_SIZE(colors32) / buf.height()];
-               uint32_t *line = (uint32_t*)(buf.map(0) + buf.stride(0) * y);
-
-               if (old_xpos >= 0) {
-                       for (int x = old_xpos; x < old_xpos + width; ++x)
-                               line[x] = 0;
+                       card.call_page_flip_handlers();
                }
-
-               for (int x = xpos; x < xpos + width; ++x)
-                       line[x] = bcol.raw;
-       }
-}
-
-static void drm_draw_color_bar_rgb565(Framebuffer& buf, int old_xpos, int xpos, int width)
-{
-       static_assert(ARRAY_SIZE(colors32) == ARRAY_SIZE(colors16), "bad colors arrays");
-
-       for (unsigned y = 0; y < buf.height(); ++y) {
-               uint16_t bcol = colors16[y * ARRAY_SIZE(colors16) / buf.height()];
-               uint16_t *line = (uint16_t*)(buf.map(0) + buf.stride(0) * y);
-
-               if (old_xpos >= 0) {
-                       for (int x = old_xpos; x < old_xpos + width; ++x)
-                               line[x] = 0;
-               }
-
-               for (int x = xpos; x < xpos + width; ++x)
-                       line[x] = bcol;
-       }
-}
-
-static void drm_draw_color_bar_semiplanar_yuv(Framebuffer& buf, int old_xpos, int xpos, int width)
-{
-       const uint8_t colors[] = {
-               0xff,
-               0x00,
-               0xff,
-               0x20,
-               0xff,
-               0x40,
-               0xff,
-               0x80,
-               0xff,
-       };
-
-       for (unsigned y = 0; y < buf.height(); ++y) {
-               unsigned int bcol = colors[y * ARRAY_SIZE(colors) / buf.height()];
-               uint8_t *line = (uint8_t*)(buf.map(0) + buf.stride(0) * y);
-
-               if (old_xpos >= 0) {
-                       for (int x = old_xpos; x < old_xpos + width; ++x)
-                               line[x] = 0;
-               }
-
-               for (int x = xpos; x < xpos + width; ++x)
-                       line[x] = bcol;
-       }
-}
-
-static void draw_color_bar(Framebuffer& buf, int old_xpos, int xpos, int width)
-{
-       switch (buf.format()) {
-       case DRM_FORMAT_NV12:
-       case DRM_FORMAT_NV21:
-               // XXX not right but gets something on the screen
-               drm_draw_color_bar_semiplanar_yuv(buf, old_xpos, xpos, width);
-               break;
-
-       case DRM_FORMAT_YUYV:
-       case DRM_FORMAT_UYVY:
-               // XXX not right but gets something on the screen
-               drm_draw_color_bar_rgb565(buf, old_xpos, xpos, width);
-               break;
-
-       case DRM_FORMAT_RGB565:
-               drm_draw_color_bar_rgb565(buf, old_xpos, xpos, width);
-               break;
-
-       case DRM_FORMAT_XRGB8888:
-               drm_draw_color_bar_rgb888(buf, old_xpos, xpos, width);
-               break;
-
-       default:
-               ASSERT(false);
        }
 }