kmacapture: atomic modesetting support
authorTomi Valkeinen <tomi.valkeinen@ti.com>
Tue, 26 Apr 2016 08:54:40 +0000 (11:54 +0300)
committerTomi Valkeinen <tomi.valkeinen@ti.com>
Tue, 26 Apr 2016 08:58:31 +0000 (11:58 +0300)
tests/kmscapture.cpp

index 4e81003a6c11323afa0cee836b7e0ed11e16bf86..965d32e22158053f98a6d34dd5c3c63836fdd0ce 100644 (file)
@@ -27,7 +27,7 @@ enum class BufferProvider {
 class CameraPipeline
 {
 public:
 class CameraPipeline
 {
 public:
-       CameraPipeline(int cam_fd, Card& card, Plane* plane, uint32_t x, uint32_t y,
+       CameraPipeline(int cam_fd, Card& card, Crtc* crtc, Plane* plane, uint32_t x, uint32_t y,
                       uint32_t iw, uint32_t ih, PixelFormat pixfmt,
                       BufferProvider buffer_provider);
        ~CameraPipeline();
                       uint32_t iw, uint32_t ih, PixelFormat pixfmt,
                       BufferProvider buffer_provider);
        ~CameraPipeline();
@@ -35,11 +35,12 @@ public:
        CameraPipeline(const CameraPipeline& other) = delete;
        CameraPipeline& operator=(const CameraPipeline& other) = delete;
 
        CameraPipeline(const CameraPipeline& other) = delete;
        CameraPipeline& operator=(const CameraPipeline& other) = delete;
 
-       void show_next_frame(Crtc* crtc);
+       void show_next_frame(AtomicReq &req);
        int fd() const { return m_fd; }
 private:
        ExtFramebuffer* GetExtFrameBuffer(Card& card, uint32_t i, PixelFormat pixfmt);
        int m_fd;       /* camera file descriptor */
        int fd() const { return m_fd; }
 private:
        ExtFramebuffer* GetExtFrameBuffer(Card& card, uint32_t i, PixelFormat pixfmt);
        int m_fd;       /* camera file descriptor */
+       Crtc* m_crtc;
        Plane* m_plane;
        BufferProvider m_buffer_provider;
        vector<DumbFramebuffer*> m_fb; /* framebuffers for DRM buffers */
        Plane* m_plane;
        BufferProvider m_buffer_provider;
        vector<DumbFramebuffer*> m_fb; /* framebuffers for DRM buffers */
@@ -101,11 +102,12 @@ bool inline better_size(struct v4l2_frmsize_discrete* v4ldisc,
        return false;
 }
 
        return false;
 }
 
-CameraPipeline::CameraPipeline(int cam_fd, Card& card, Plane* plane, uint32_t x, uint32_t y,
+CameraPipeline::CameraPipeline(int cam_fd, Card& card, Crtc *crtc, Plane* plane, uint32_t x, uint32_t y,
                               uint32_t iw, uint32_t ih, PixelFormat pixfmt,
                               BufferProvider buffer_provider)
                               uint32_t iw, uint32_t ih, PixelFormat pixfmt,
                               BufferProvider buffer_provider)
-       : m_fd(cam_fd), m_buffer_provider(buffer_provider)
+       : m_fd(cam_fd), m_crtc(crtc), m_buffer_provider(buffer_provider), m_prev_fb_index(-1)
 {
 {
+
        int r;
        uint32_t best_w = 320;
        uint32_t best_h = 240;
        int r;
        uint32_t best_w = 320;
        uint32_t best_h = 240;
@@ -183,13 +185,39 @@ CameraPipeline::CameraPipeline(int cam_fd, Card& card, Plane* plane, uint32_t x,
                else
                        m_fb.push_back(fb);
        }
                else
                        m_fb.push_back(fb);
        }
-       m_prev_fb_index = -1;
+
        enum v4l2_buf_type type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
 
        r = ioctl(m_fd, VIDIOC_STREAMON, &type);
        ASSERT(r == 0);
 
        m_plane = plane;
        enum v4l2_buf_type type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
 
        r = ioctl(m_fd, VIDIOC_STREAMON, &type);
        ASSERT(r == 0);
 
        m_plane = plane;
+
+       // Do initial plane setup with first fb, so that we only need to
+       // set the FB when page flipping
+       AtomicReq req(card);
+
+       Framebuffer *fb;
+       if (m_buffer_provider == BufferProvider::V4L2)
+               fb = m_extfb[0];
+       else
+               fb = m_fb[0];
+
+       req.add(m_plane, "CRTC_ID", m_crtc->id());
+       req.add(m_plane, "FB_ID", fb->id());
+
+       req.add(m_plane, "CRTC_X", m_out_x);
+       req.add(m_plane, "CRTC_Y", m_out_y);
+       req.add(m_plane, "CRTC_W", m_out_width);
+       req.add(m_plane, "CRTC_H", m_out_height);
+
+       req.add(m_plane, "SRC_X", 0);
+       req.add(m_plane, "SRC_Y", 0);
+       req.add(m_plane, "SRC_W", m_in_width << 16);
+       req.add(m_plane, "SRC_H", m_in_height << 16);
+
+       r = req.commit_sync();
+       FAIL_IF(r, "initial plane setup failed");
 }
 
 
 }
 
 
@@ -204,7 +232,7 @@ CameraPipeline::~CameraPipeline()
        ::close(m_fd);
 }
 
        ::close(m_fd);
 }
 
-void CameraPipeline::show_next_frame(Crtc* crtc)
+void CameraPipeline::show_next_frame(AtomicReq& req)
 {
        int r;
        uint32_t v4l_mem;
 {
        int r;
        uint32_t v4l_mem;
@@ -224,16 +252,14 @@ void CameraPipeline::show_next_frame(Crtc* crtc)
        }
 
        unsigned fb_index = v4l2buf.index;
        }
 
        unsigned fb_index = v4l2buf.index;
+
+       Framebuffer *fb;
        if (m_buffer_provider == BufferProvider::V4L2)
        if (m_buffer_provider == BufferProvider::V4L2)
-               r = crtc->set_plane(m_plane, *m_extfb[fb_index],
-                                   m_out_x, m_out_y, m_out_width, m_out_height,
-                                   0, 0, m_in_width, m_in_height);
+               fb = m_extfb[fb_index];
        else
        else
-               r = crtc->set_plane(m_plane, *m_fb[fb_index],
-                                   m_out_x, m_out_y, m_out_width, m_out_height,
-                                   0, 0, m_in_width, m_in_height);
+               fb = m_fb[fb_index];
 
 
-       ASSERT(r == 0);
+       req.add(m_plane, "FB_ID", fb->id());
 
        if (m_prev_fb_index >= 0) {
                memset(&v4l2buf, 0, sizeof(v4l2buf));
 
        if (m_prev_fb_index >= 0) {
                memset(&v4l2buf, 0, sizeof(v4l2buf));
@@ -246,6 +272,7 @@ void CameraPipeline::show_next_frame(Crtc* crtc)
                ASSERT(r == 0);
 
        }
                ASSERT(r == 0);
 
        }
+
        m_prev_fb_index = fb_index;
 }
 
        m_prev_fb_index = fb_index;
 }
 
@@ -359,7 +386,7 @@ int main(int argc, char** argv)
                int cam_fd = camera_fds[i];
                Plane* plane = available_planes[i];
 
                int cam_fd = camera_fds[i];
                Plane* plane = available_planes[i];
 
-               auto cam = new CameraPipeline(cam_fd, card, plane, i * plane_w, 0,
+               auto cam = new CameraPipeline(cam_fd, card, crtc, plane, i * plane_w, 0,
                                              plane_w, crtc->height(), pixfmt, buffer_provider);
                cameras.push_back(cam);
        }
                                              plane_w, crtc->height(), pixfmt, buffer_provider);
                cameras.push_back(cam);
        }
@@ -382,12 +409,19 @@ int main(int argc, char** argv)
                if (fds[nr_cameras].revents != 0)
                        break;
 
                if (fds[nr_cameras].revents != 0)
                        break;
 
+               AtomicReq req(card);
+
                for (unsigned i = 0; i < nr_cameras; i++) {
                        if (!fds[i].revents)
                                continue;
                for (unsigned i = 0; i < nr_cameras; i++) {
                        if (!fds[i].revents)
                                continue;
-                       cameras[i]->show_next_frame(crtc);
+                       cameras[i]->show_next_frame(req);
                        fds[i].revents = 0;
                }
                        fds[i].revents = 0;
                }
+
+               r = req.test();
+               FAIL_IF(r, "Atomic commit failed: %d", r);
+
+               req.commit();
        }
 
        for (auto cam : cameras)
        }
 
        for (auto cam : cameras)