summaryrefslogtreecommitdiff
path: root/tests
diff options
context:
space:
mode:
authorTomi Valkeinen <tomi.valkeinen@ti.com>2016-05-23 09:54:08 +0300
committerTomi Valkeinen <tomi.valkeinen@ti.com>2016-05-23 09:54:08 +0300
commita5c28bcb2ead34e921617711ebf94ffcb5d72878 (patch)
treee2f93259f63407357c70b06a7d59c24fde5a3901 /tests
parent0bc5bbd6766949d651f98e12981d79c86ce0bf99 (diff)
File/dir renames
Diffstat (limited to 'tests')
-rw-r--r--tests/CMakeLists.txt20
-rw-r--r--tests/db.cpp265
-rw-r--r--tests/fbtestpat.cpp60
-rw-r--r--tests/kmscapture.cpp435
-rw-r--r--tests/kmsprint.cpp221
-rw-r--r--tests/kmsview.cpp92
-rw-r--r--tests/testpat.cpp604
7 files changed, 0 insertions, 1697 deletions
diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt
deleted file mode 100644
index bb335d3..0000000
--- a/tests/CMakeLists.txt
+++ /dev/null
@@ -1,20 +0,0 @@
-include_directories(${LIBDRM_INCLUDE_DIRS})
-link_directories(${LIBDRM_LIBRARY_DIRS})
-
-add_executable (db db.cpp)
-target_link_libraries(db kms++ kmstest ${LIBDRM_LIBRARIES})
-
-add_executable (testpat testpat.cpp)
-target_link_libraries(testpat kms++ kmstest ${LIBDRM_LIBRARIES})
-
-add_executable (kmsview kmsview.cpp)
-target_link_libraries(kmsview kms++ kmstest ${LIBDRM_LIBRARIES})
-
-add_executable (kmsprint kmsprint.cpp)
-target_link_libraries(kmsprint kms++ kmstest ${LIBDRM_LIBRARIES})
-
-add_executable (fbtestpat fbtestpat.cpp)
-target_link_libraries(fbtestpat kmstest)
-
-add_executable (kmscapture kmscapture.cpp)
-target_link_libraries(kmscapture kms++ kmstest ${LIBDRM_LIBRARIES})
diff --git a/tests/db.cpp b/tests/db.cpp
deleted file mode 100644
index 3e8420b..0000000
--- a/tests/db.cpp
+++ /dev/null
@@ -1,265 +0,0 @@
-#include <cstdio>
-#include <algorithm>
-#include <chrono>
-
-#include <xf86drm.h>
-#include <xf86drmMode.h>
-#include <drm_fourcc.h>
-
-#include "kms++.h"
-
-#include "test.h"
-
-using namespace std;
-using namespace kms;
-
-static void main_loop(Card& card);
-
-class Flipper
-{
-public:
- 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);
- }
-
- ~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 fb = m_flipper.get_next();
- int r = m_crtc->set_mode(m_connector, *fb, m_mode);
- ASSERT(r == 0);
-
- if (m_crtc->card().has_atomic())
- m_root_plane = m_crtc->get_primary_plane();
-
- 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 start_flipping()
- {
- m_time_last = m_t1 = std::chrono::steady_clock::now();
- m_slowest_frame = std::chrono::duration<float>::min();
- m_frame_num = 0;
- queue_next();
- }
-
-private:
- void handle_page_flip(uint32_t frame, double time)
- {
- ++m_frame_num;
-
- auto now = std::chrono::steady_clock::now();
-
- std::chrono::duration<float> diff = now - m_time_last;
- if (diff > m_slowest_frame)
- m_slowest_frame = diff;
-
- 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();
- }
-
- m_time_last = now;
-
- 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 req(card);
-
- req.add(m_root_plane, "FB_ID", fb->id());
- if (m_plane)
- req.add(m_plane, "FB_ID", planefb->id());
-
- r = req.test();
- ASSERT(r == 0);
-
- r = req.commit(this);
- ASSERT(r == 0);
- } else {
- 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;
- Videomode m_mode;
- Plane* m_root_plane;
-
- 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()
-{
- Card card;
-
- if (card.master() == false)
- printf("Not DRM master, modeset may fail\n");
-
- vector<OutputFlipHandler*> outputs;
-
- for (auto pipe : card.get_connected_pipelines())
- {
- auto conn = pipe.connector;
- auto crtc = pipe.crtc;
- auto mode = conn->get_default_mode();
-
-
- 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);
- }
-
- for(auto out : outputs)
- out->set_mode();
-
- for(auto out : outputs)
- out->start_flipping();
-
- main_loop(card);
-
- for(auto out : outputs)
- delete out;
-}
-
-static void main_loop(Card& card)
-{
- fd_set fds;
-
- FD_ZERO(&fds);
-
- int fd = card.fd();
-
- printf("press enter to exit\n");
-
- while (true) {
- int r;
-
- FD_SET(0, &fds);
- FD_SET(fd, &fds);
-
- r = select(fd + 1, &fds, NULL, NULL, NULL);
- if (r < 0) {
- fprintf(stderr, "select() failed with %d: %m\n", errno);
- break;
- } else if (FD_ISSET(0, &fds)) {
- fprintf(stderr, "exit due to user-input\n");
- break;
- } else if (FD_ISSET(fd, &fds)) {
- card.call_page_flip_handlers();
- }
- }
-}
diff --git a/tests/fbtestpat.cpp b/tests/fbtestpat.cpp
deleted file mode 100644
index d82f3e4..0000000
--- a/tests/fbtestpat.cpp
+++ /dev/null
@@ -1,60 +0,0 @@
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <errno.h>
-#include <fcntl.h>
-#include <unistd.h>
-
-#include <sys/ioctl.h>
-#include <sys/stat.h>
-#include <sys/mman.h>
-
-#include <linux/fb.h>
-
-#include "test.h"
-#include "extcpuframebuffer.h"
-
-using namespace kms;
-
-int main(int argc, char** argv)
-{
- const char* fbdev = "/dev/fb0";
- int r;
-
- int fd = open(fbdev, O_RDWR);
- FAIL_IF(fd < 0, "open %s failed\n", fbdev);
-
- struct fb_var_screeninfo var;
-
- r = ioctl(fd, FBIOGET_VSCREENINFO, &var);
- FAIL_IF(r, "FBIOGET_VSCREENINFO failed");
-
- struct fb_fix_screeninfo fix;
-
- r = ioctl(fd, FBIOGET_FSCREENINFO, &fix);
- FAIL_IF(r, "FBIOGET_FSCREENINFO failed");
-
- uint8_t* ptr = (uint8_t*)mmap(NULL,
- var.yres_virtual * fix.line_length,
- PROT_WRITE | PROT_READ,
- MAP_SHARED, fd, 0);
-
- FAIL_IF(ptr == MAP_FAILED, "mmap failed");
-
- ExtCPUFramebuffer buf(var.xres, var.yres_virtual, PixelFormat::XRGB8888, ptr, fix.line_length);
-
- printf("%s: res %dx%d, virtual %dx%d, line_len %d\n",
- fbdev,
- var.xres, var.yres,
- var.xres_virtual, var.yres_virtual,
- fix.line_length);
-
- draw_test_pattern(buf);
-
- for (unsigned y = 0; y < var.yres_virtual; ++y)
- memcpy(ptr + fix.line_length * y, buf.map(0) + buf.stride(0) * y, buf.stride(0));
-
- close(fd);
-
- return 0;
-}
diff --git a/tests/kmscapture.cpp b/tests/kmscapture.cpp
deleted file mode 100644
index ee700b7..0000000
--- a/tests/kmscapture.cpp
+++ /dev/null
@@ -1,435 +0,0 @@
-#include <linux/videodev2.h>
-#include <cstdio>
-#include <string.h>
-#include <poll.h>
-#include <fcntl.h>
-#include <unistd.h>
-#include <fstream>
-#include <sys/ioctl.h>
-#include <xf86drm.h>
-#include <glob.h>
-
-#include "kms++.h"
-#include "test.h"
-#include "opts.h"
-
-#define CAMERA_BUF_QUEUE_SIZE 3
-#define MAX_CAMERA 9
-
-using namespace std;
-using namespace kms;
-
-enum class BufferProvider {
- DRM,
- V4L2,
-};
-
-class CameraPipeline
-{
-public:
- 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();
-
- CameraPipeline(const CameraPipeline& other) = delete;
- CameraPipeline& operator=(const CameraPipeline& other) = delete;
-
- void show_next_frame(AtomicReq &req);
- int fd() const { return m_fd; }
- void start_streaming();
-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 */
- vector<ExtFramebuffer*> m_extfb; /* framebuffers for V4L2 buffers */
- int m_prev_fb_index;
- uint32_t m_in_width, m_in_height; /* camera capture resolution */
- /* image properties for display */
- uint32_t m_out_width, m_out_height;
- uint32_t m_out_x, m_out_y;
-};
-
-static int buffer_export(int v4lfd, enum v4l2_buf_type bt, uint32_t index, int *dmafd)
-{
- struct v4l2_exportbuffer expbuf;
-
- memset(&expbuf, 0, sizeof(expbuf));
- expbuf.type = bt;
- expbuf.index = index;
- if (ioctl(v4lfd, VIDIOC_EXPBUF, &expbuf) == -1) {
- perror("VIDIOC_EXPBUF");
- return -1;
- }
-
- *dmafd = expbuf.fd;
-
- return 0;
-}
-
-ExtFramebuffer* CameraPipeline::GetExtFrameBuffer(Card& card, uint32_t i, PixelFormat pixfmt)
-{
- int r, dmafd;
-
- r = buffer_export(m_fd, V4L2_BUF_TYPE_VIDEO_CAPTURE, i, &dmafd);
- ASSERT(r == 0);
-
- uint32_t handle;
- r = drmPrimeFDToHandle(card.fd(), dmafd, &handle);
- ASSERT(r == 0);
-
- const PixelFormatInfo& format_info = get_pixel_format_info(pixfmt);
- ASSERT(format_info.num_planes == 1);
-
- uint32_t handles[4] { handle };
- uint32_t pitches[4] { m_in_width * (format_info.planes[0].bitspp / 8) };
- uint32_t offsets[4] { };
-
- return new ExtFramebuffer(card, m_in_width, m_in_height, pixfmt,
- handles, pitches, offsets);
-}
-
-bool inline better_size(struct v4l2_frmsize_discrete* v4ldisc,
- uint32_t iw, uint32_t ih,
- uint32_t best_w, uint32_t best_h)
-{
- if (v4ldisc->width <= iw && v4ldisc->height <= ih &&
- (v4ldisc->width >= best_w || v4ldisc->height >= best_h))
- return true;
-
- return false;
-}
-
-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)
- : 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;
-
- struct v4l2_frmsizeenum v4lfrms = { };
- v4lfrms.pixel_format = (uint32_t)pixfmt;
- while (ioctl(m_fd, VIDIOC_ENUM_FRAMESIZES, &v4lfrms) == 0) {
- if (v4lfrms.type == V4L2_FRMSIZE_TYPE_DISCRETE) {
- if (better_size(&v4lfrms.discrete, iw, ih,
- best_w, best_h)) {
- best_w = v4lfrms.discrete.width;
- best_h = v4lfrms.discrete.height;
- }
- } else {
- break;
- }
- v4lfrms.index++;
- };
-
- m_out_width = m_in_width = best_w;
- m_out_height = m_in_height = best_h;
- /* Move it to the middle of the requested area */
- m_out_x = x + iw / 2 - m_out_width / 2;
- m_out_y = y + ih / 2 - m_out_height / 2;
-
- struct v4l2_format v4lfmt = { };
- v4lfmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
- r = ioctl(m_fd, VIDIOC_G_FMT, &v4lfmt);
- ASSERT(r == 0);
-
- v4lfmt.fmt.pix.pixelformat = (uint32_t)pixfmt;
- v4lfmt.fmt.pix.width = m_in_width;
- v4lfmt.fmt.pix.height = m_in_height;
-
- r = ioctl(m_fd, VIDIOC_S_FMT, &v4lfmt);
- ASSERT(r == 0);
-
- uint32_t v4l_mem;
-
- if (m_buffer_provider == BufferProvider::V4L2)
- v4l_mem = V4L2_MEMORY_MMAP;
- else
- v4l_mem = V4L2_MEMORY_DMABUF;
-
- struct v4l2_requestbuffers v4lreqbuf = { };
- v4lreqbuf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
- v4lreqbuf.memory = v4l_mem;
- v4lreqbuf.count = CAMERA_BUF_QUEUE_SIZE;
- r = ioctl(m_fd, VIDIOC_REQBUFS, &v4lreqbuf);
- ASSERT(r == 0);
- ASSERT(v4lreqbuf.count == CAMERA_BUF_QUEUE_SIZE);
-
- struct v4l2_buffer v4lbuf = { };
- v4lbuf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
- v4lbuf.memory = v4l_mem;
-
- for (unsigned i = 0; i < CAMERA_BUF_QUEUE_SIZE; i++) {
- DumbFramebuffer *fb = NULL;
- ExtFramebuffer *extfb = NULL;
-
- if (m_buffer_provider == BufferProvider::V4L2)
- extfb = GetExtFrameBuffer(card, i, pixfmt);
- else
- fb = new DumbFramebuffer(card, m_in_width,
- m_in_height, pixfmt);
-
- v4lbuf.index = i;
- if (m_buffer_provider == BufferProvider::DRM)
- v4lbuf.m.fd = fb->prime_fd(0);
- r = ioctl(m_fd, VIDIOC_QBUF, &v4lbuf);
- ASSERT(r == 0);
-
- if (m_buffer_provider == BufferProvider::V4L2)
- m_extfb.push_back(extfb);
- else
- m_fb.push_back(fb);
- }
-
- 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");
-}
-
-CameraPipeline::~CameraPipeline()
-{
- for (unsigned i = 0; i < m_fb.size(); i++)
- delete m_fb[i];
-
- for (unsigned i = 0; i < m_extfb.size(); i++)
- delete m_extfb[i];
-
- ::close(m_fd);
-}
-
-void CameraPipeline::start_streaming()
-{
- enum v4l2_buf_type type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
-
- int r = ioctl(m_fd, VIDIOC_STREAMON, &type);
- FAIL_IF(r, "Failed to enable camera stream: %d", r);
-}
-
-void CameraPipeline::show_next_frame(AtomicReq& req)
-{
- int r;
- uint32_t v4l_mem;
-
- if (m_buffer_provider == BufferProvider::V4L2)
- v4l_mem = V4L2_MEMORY_MMAP;
- else
- v4l_mem = V4L2_MEMORY_DMABUF;
-
- struct v4l2_buffer v4l2buf = { };
- v4l2buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
- v4l2buf.memory = v4l_mem;
- r = ioctl(m_fd, VIDIOC_DQBUF, &v4l2buf);
- if (r != 0) {
- printf("VIDIOC_DQBUF ioctl failed with %d\n", errno);
- return;
- }
-
- unsigned fb_index = v4l2buf.index;
-
- Framebuffer *fb;
- if (m_buffer_provider == BufferProvider::V4L2)
- fb = m_extfb[fb_index];
- else
- fb = m_fb[fb_index];
-
- req.add(m_plane, "FB_ID", fb->id());
-
- if (m_prev_fb_index >= 0) {
- memset(&v4l2buf, 0, sizeof(v4l2buf));
- v4l2buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
- v4l2buf.memory = v4l_mem;
- v4l2buf.index = m_prev_fb_index;
- if (m_buffer_provider == BufferProvider::DRM)
- v4l2buf.m.fd = m_fb[m_prev_fb_index]->prime_fd(0);
- r = ioctl(m_fd, VIDIOC_QBUF, &v4l2buf);
- ASSERT(r == 0);
-
- }
-
- m_prev_fb_index = fb_index;
-}
-
-static bool is_capture_dev(int fd)
-{
- struct v4l2_capability cap = { };
- int r = ioctl(fd, VIDIOC_QUERYCAP, &cap);
- ASSERT(r == 0);
- return cap.capabilities & V4L2_CAP_VIDEO_CAPTURE;
-}
-
-std::vector<std::string> glob(const std::string& pat)
-{
- glob_t glob_result;
- glob(pat.c_str(), 0, NULL, &glob_result);
- vector<string> ret;
- for(unsigned i = 0; i < glob_result.gl_pathc; ++i)
- ret.push_back(string(glob_result.gl_pathv[i]));
- globfree(&glob_result);
- return ret;
-}
-
-static const char* usage_str =
- "Usage: kmscapture [OPTIONS]\n\n"
- "Options:\n"
- " -s, --single Single camera mode. Open only /dev/video0\n"
- " --buffer-type=<drm|v4l> Use DRM or V4L provided buffers. Default: DRM\n"
- " -h, --help Print this help\n"
- ;
-
-int main(int argc, char** argv)
-{
- BufferProvider buffer_provider = BufferProvider::DRM;
- bool single_cam = false;
-
- OptionSet optionset = {
- Option("s|single", [&]()
- {
- single_cam = true;
- }),
- Option("|buffer-type=", [&](string s)
- {
- if (s == "v4l")
- buffer_provider = BufferProvider::V4L2;
- else if (s == "drm")
- buffer_provider = BufferProvider::DRM;
- else
- FAIL("Invalid buffer provider: %s", s.c_str());
- }),
- Option("h|help", [&]()
- {
- puts(usage_str);
- exit(-1);
- }),
- };
-
- optionset.parse(argc, argv);
-
- if (optionset.params().size() > 0) {
- puts(usage_str);
- exit(-1);
- }
-
- auto pixfmt = PixelFormat::YUYV;
-
- Card card;
-
- auto conn = card.get_first_connected_connector();
- auto crtc = conn->get_current_crtc();
- printf("Display: %dx%d\n", crtc->width(), crtc->height());
- printf("Buffer provider: %s\n", buffer_provider == BufferProvider::V4L2? "V4L" : "DRM");
-
- vector<int> camera_fds;
-
- for (string vidpath : glob("/dev/video*")) {
- int fd = ::open(vidpath.c_str(), O_RDWR | O_NONBLOCK);
-
- if (fd < 0)
- continue;
-
- if (!is_capture_dev(fd)) {
- close(fd);
- continue;
- }
-
- camera_fds.push_back(fd);
-
- if (single_cam)
- break;
- }
-
- FAIL_IF(camera_fds.size() == 0, "No cameras found");
-
- vector<Plane*> available_planes;
- for (Plane* p : crtc->get_possible_planes()) {
- if (p->plane_type() != PlaneType::Overlay)
- continue;
-
- if (!p->supports_format(pixfmt))
- continue;
-
- available_planes.push_back(p);
- }
-
- FAIL_IF(available_planes.size() < camera_fds.size(), "Not enough video planes for cameras");
-
- uint32_t plane_w = crtc->width() / camera_fds.size();
- vector<CameraPipeline*> cameras;
-
- for (unsigned i = 0; i < camera_fds.size(); ++i) {
- int cam_fd = camera_fds[i];
- Plane* plane = available_planes[i];
-
- auto cam = new CameraPipeline(cam_fd, card, crtc, plane, i * plane_w, 0,
- plane_w, crtc->height(), pixfmt, buffer_provider);
- cameras.push_back(cam);
- }
-
- unsigned nr_cameras = cameras.size();
-
- vector<pollfd> fds(nr_cameras + 1);
-
- for (unsigned i = 0; i < nr_cameras; i++) {
- fds[i].fd = cameras[i]->fd();
- fds[i].events = POLLIN;
- }
- fds[nr_cameras].fd = 0;
- fds[nr_cameras].events = POLLIN;
-
- for (auto cam : cameras)
- cam->start_streaming();
-
- while (true) {
- int r = poll(fds.data(), nr_cameras + 1, -1);
- ASSERT(r > 0);
-
- if (fds[nr_cameras].revents != 0)
- break;
-
- AtomicReq req(card);
-
- for (unsigned i = 0; i < nr_cameras; i++) {
- if (!fds[i].revents)
- continue;
- cameras[i]->show_next_frame(req);
- fds[i].revents = 0;
- }
-
- r = req.test();
- FAIL_IF(r, "Atomic commit failed: %d", r);
-
- req.commit_sync();
- }
-
- for (auto cam : cameras)
- delete cam;
-}
diff --git a/tests/kmsprint.cpp b/tests/kmsprint.cpp
deleted file mode 100644
index 7b9de8c..0000000
--- a/tests/kmsprint.cpp
+++ /dev/null
@@ -1,221 +0,0 @@
-#include <cstdio>
-#include <algorithm>
-#include <iostream>
-
-#include "kms++.h"
-#include "opts.h"
-
-using namespace std;
-using namespace kms;
-
-namespace kmsprint {
-
-static struct {
- bool print_props;
- bool print_modes;
- bool recurse;
-} opts;
-
-string width(int w, string str)
-{
- str.resize(w, ' ');
- return str;
-}
-
-void print_mode(const Videomode &m, int ind)
-{
- printf("%s%s %6d %4d %4d %4d %4d %d %4d %4d %4d %4d %d %2d 0x%04x %2d\n",
- width(ind, "").c_str(),
- m.name[0] == '\0' ? "" : width(11, m.name).c_str(),
- m.clock,
- m.hdisplay,
- m.hsync_start,
- m.hsync_end,
- m.htotal,
- m.hskew,
- m.vdisplay,
- m.vsync_start,
- m.vsync_end,
- m.vtotal,
- m.vscan,
- m.vrefresh,
- m.flags,
- m.type);
-}
-
-void print_property(uint64_t val, const Property& p, int ind)
-{
- printf("%s%s (id %d) = %s\n", width(ind, "").c_str(),
- p.name().c_str(), p.id(), p.to_str(val).c_str());
-}
-
-void print_properties(DrmObject& o, int ind)
-{
- auto pmap = o.get_prop_map();
- printf("%sProperties, %u in total:\n", width(ind, "").c_str(),
- (unsigned) pmap.size());
- for (auto pp : pmap) {
- const Property& p = *o.card().get_prop(pp.first);
- print_property(pp.second, p, ind + 2);
- }
-}
-
-void print_plane(Plane& p, int ind)
-{
- printf("%sPlane Id %d %d,%d -> %dx%d formats:", width(ind, "").c_str(),
- p.id(), p.crtc_x(), p.crtc_y(), p.x(), p.y());
- for (auto f : p.get_formats())
- printf(" %s", PixelFormatToFourCC(f).c_str());
- printf("\n");
-
- if (opts.print_props)
- print_properties(p, ind+2);
-}
-
-void print_crtc(Crtc& cc, int ind)
-{
- printf("%sCRTC Id %d BufferId %d %dx%d at %dx%d gamma_size %d\n",
- width(ind, "").c_str(), cc.id(), cc.buffer_id(), cc.width(),
- cc.height(), cc.x(), cc.y(), cc.gamma_size());
-
- printf("%s Mode ", width(ind, "").c_str());
- print_mode(cc.mode(), 0);
-
- if (opts.print_props)
- print_properties(cc, ind+2);
-
- if (opts.recurse)
- for (auto p : cc.get_possible_planes())
- print_plane(*p, ind + 2);
-}
-
-void print_encoder(Encoder& e, int ind)
-{
- printf("%sEncoder Id %d type %s\n", width(ind, "").c_str(),
- e.id(), e.get_encoder_type().c_str());
-
- if (opts.print_props)
- print_properties(e, ind+2);
-
- if (opts.recurse)
- for (auto cc : e.get_possible_crtcs())
- print_crtc(*cc, ind + 2);
-}
-
-void print_connector(Connector& c, int ind)
-{
- printf("%sConnector %s Id %d %sconnected", width(ind, "").c_str(),
- c.fullname().c_str(), c.id(), c.connected() ? "" : "dis");
- if (c.subpixel() != 0)
- printf(" Subpixel: %s", c.subpixel_str().c_str());
- printf("\n");
-
- if (opts.print_props)
- print_properties(c, ind+2);
-
- if (opts.recurse)
- for (auto enc : c.get_encoders())
- print_encoder(*enc, ind + 2);
-
- if (opts.print_modes) {
- auto modes = c.get_modes();
- printf("%sModes, %u in total:\n", width(ind + 2, "").c_str(),
- (unsigned) modes.size());
- for (auto mode : modes)
- print_mode(mode, ind + 3);
- }
-}
-
-}
-
-using namespace kmsprint;
-
-static const char* usage_str =
- "Usage: kmsprint [OPTIONS]\n\n"
- "Options:\n"
- " -m, --modes Print modes\n"
- " -p, --props Print properties\n"
- " -r, --recurse Recursively print all related objects\n"
- " --id=<ID> Print object <ID>\n"
- ;
-
-static void usage()
-{
- puts(usage_str);
-}
-
-int main(int argc, char **argv)
-{
- string dev_path;
- unsigned id = 0;
-
- OptionSet optionset = {
- Option("|device=",
- [&](string s)
- {
- dev_path = s;
- }),
- Option("|id=",
- [&](string s)
- {
- id = stoul(s);
- }),
- Option("p", [&](string s)
- {
- opts.print_props = true;
- }),
- Option("m", [&](string s)
- {
- opts.print_modes = true;
- }),
- Option("r", [&](string s)
- {
- opts.recurse = true;
- }),
- Option("h|help", [&]()
- {
- usage();
- exit(-1);
- }),
- };
-
- optionset.parse(argc, argv);
-
- if (optionset.params().size() > 0) {
- usage();
- exit(-1);
- }
-
- Card card;
-
- /* No options impliles recursion */
- if (id == 0) {
- opts.recurse = true;
- for (auto conn : card.get_connectors())
- print_connector(*conn, 0);
- return 0;
- } else {
- auto ob = card.get_object(id);
- if (!ob) {
- cerr << "kmsprint" << ": Object id " <<
- id << " not found." << endl;
- return -1;
- }
-
- if (auto co = dynamic_cast<Connector*>(ob))
- print_connector(*co, 0);
- else if (auto en = dynamic_cast<Encoder*>(ob))
- print_encoder(*en, 0);
- else if (auto cr = dynamic_cast<Crtc*>(ob))
- print_crtc(*cr, 0);
- else if (auto pl = dynamic_cast<Plane*>(ob))
- print_plane(*pl, 0);
- else {
- cerr << "kmsprint" << ": Unkown DRM Object type" <<
- endl;
- return -1;
- }
-
- return 0;
- }
-}
diff --git a/tests/kmsview.cpp b/tests/kmsview.cpp
deleted file mode 100644
index aae7e80..0000000
--- a/tests/kmsview.cpp
+++ /dev/null
@@ -1,92 +0,0 @@
-#include <cstdio>
-#include <fstream>
-#include <unistd.h>
-
-#include "kms++.h"
-
-#include "test.h"
-
-using namespace std;
-using namespace kms;
-
-static void read_frame(ifstream& is, DumbFramebuffer* fb, Crtc* crtc, Plane* plane)
-{
- for (unsigned i = 0; i < fb->num_planes(); ++i)
- is.read((char*)fb->map(i), fb->size(i));
-
- unsigned w = min(crtc->width(), fb->width());
- unsigned h = min(crtc->height(), fb->height());
-
- int r = crtc->set_plane(plane, *fb,
- 0, 0, w, h,
- 0, 0, fb->width(), fb->height());
-
- ASSERT(r == 0);
-}
-
-int main(int argc, char** argv)
-{
- if (argc != 5) {
- printf("Usage: %s <file> <width> <height> <fourcc>\n", argv[0]);
- return -1;
- }
-
- string filename = argv[1];
- uint32_t w = stoi(argv[2]);
- uint32_t h = stoi(argv[3]);
- string modestr = argv[4];
-
- auto pixfmt = FourCCToPixelFormat(modestr);
-
-
- ifstream is(filename, ifstream::binary);
-
- is.seekg(0, std::ios::end);
- unsigned fsize = is.tellg();
- is.seekg(0);
-
-
- Card card;
-
- auto conn = card.get_first_connected_connector();
- auto crtc = conn->get_current_crtc();
-
- auto fb = new DumbFramebuffer(card, w, h, pixfmt);
-
- Plane* plane = 0;
-
- for (Plane* p : crtc->get_possible_planes()) {
- if (p->plane_type() != PlaneType::Overlay)
- continue;
-
- if (!p->supports_format(pixfmt))
- continue;
-
- plane = p;
- break;
- }
-
- FAIL_IF(!plane, "available plane not found");
-
-
- unsigned frame_size = 0;
- for (unsigned i = 0; i < fb->num_planes(); ++i)
- frame_size += fb->size(i);
-
- unsigned num_frames = fsize / frame_size;
- printf("file size %u, frame size %u, frames %u\n", fsize, frame_size, num_frames);
-
- for (unsigned i = 0; i < num_frames; ++i) {
- printf("frame %d\n", i);
- read_frame(is, fb, crtc, plane);
- usleep(1000*50);
- }
-
- printf("press enter to exit\n");
-
- is.close();
-
- getchar();
-
- delete fb;
-}
diff --git a/tests/testpat.cpp b/tests/testpat.cpp
deleted file mode 100644
index ede176c..0000000
--- a/tests/testpat.cpp
+++ /dev/null
@@ -1,604 +0,0 @@
-#include <cstdio>
-#include <cstring>
-#include <algorithm>
-#include <regex>
-#include <set>
-
-#include "kms++.h"
-#include "modedb.h"
-
-#include "test.h"
-#include "opts.h"
-
-using namespace std;
-using namespace kms;
-
-struct PlaneInfo
-{
- Plane* plane;
-
- unsigned x;
- unsigned y;
- unsigned w;
- unsigned h;
-
- DumbFramebuffer* fb;
-};
-
-struct OutputInfo
-{
- Connector* connector;
-
- Crtc* crtc;
- Videomode mode;
- bool user_set_crtc;
- DumbFramebuffer* fb;
-
- vector<PlaneInfo> planes;
-};
-
-static bool s_use_dmt;
-static bool s_use_cea;
-
-static set<Crtc*> s_used_crtcs;
-static set<Plane*> s_used_planes;
-
-__attribute__ ((unused))
-static void print_regex_match(smatch sm)
-{
- for (unsigned i = 0; i < sm.size(); ++i) {
- string str = sm[i].str();
- printf("%u: %s\n", i, str.c_str());
- }
-}
-
-static void get_default_connector(Card& card, OutputInfo& output)
-{
- output.connector = card.get_first_connected_connector();
- output.mode = output.connector->get_default_mode();
-}
-
-static void parse_connector(Card& card, const string& str, OutputInfo& output)
-{
- Connector* conn = nullptr;
-
- auto connectors = card.get_connectors();
-
- if (str[0] == '@') {
- char* endptr;
- unsigned idx = strtoul(str.c_str() + 1, &endptr, 10);
- if (*endptr == 0) {
- if (idx >= connectors.size())
- EXIT("Bad connector number '%u'", idx);
-
- conn = connectors[idx];
- }
- } else {
- char* endptr;
- unsigned id = strtoul(str.c_str(), &endptr, 10);
- if (*endptr == 0) {
- Connector* c = card.get_connector(id);
- if (!c)
- EXIT("Bad connector id '%u'", id);
-
- conn = c;
- }
- }
-
- if (!conn) {
- auto iter = find_if(connectors.begin(), connectors.end(), [&str](Connector *c) { return c->fullname() == str; });
- if (iter != connectors.end())
- conn = *iter;
- }
-
- if (!conn)
- EXIT("No connector '%s'", str.c_str());
-
- if (!conn->connected())
- EXIT("Connector '%s' not connected", conn->fullname().c_str());
-
- output.connector = conn;
- output.mode = output.connector->get_default_mode();
-}
-
-static void get_default_crtc(Card& card, OutputInfo& output)
-{
- Crtc* crtc = output.connector->get_current_crtc();
-
- if (crtc && s_used_crtcs.find(crtc) == s_used_crtcs.end()) {
- s_used_crtcs.insert(crtc);
- output.crtc = crtc;
- return;
- }
-
- for (const auto& possible : output.connector->get_possible_crtcs()) {
- if (s_used_crtcs.find(possible) == s_used_crtcs.end()) {
- s_used_crtcs.insert(possible);
- output.crtc = possible;
- return;
- }
- }
-
- EXIT("Could not find available crtc");
-}
-
-static void parse_crtc(Card& card, const string& crtc_str, OutputInfo& output)
-{
- // @12:1920x1200@60
- const regex mode_re("(?:(@?)(\\d+):)?(?:(\\d+)x(\\d+)(i)?)(?:@(\\d+))?");
-
- smatch sm;
- if (!regex_match(crtc_str, sm, mode_re))
- EXIT("Failed to parse crtc option '%s'", crtc_str.c_str());
-
- if (sm[2].matched) {
- bool use_idx = sm[1].length() == 1;
- unsigned num = stoul(sm[2].str());
-
- if (use_idx) {
- auto crtcs = card.get_crtcs();
-
- if (num >= crtcs.size())
- EXIT("Bad crtc number '%u'", num);
-
- output.crtc = crtcs[num];
- } else {
- Crtc* c = card.get_crtc(num);
- if (!c)
- EXIT("Bad crtc id '%u'", num);
-
- output.crtc = c;
- }
- } else {
- output.crtc = output.connector->get_current_crtc();
- }
-
- unsigned w = stoul(sm[3]);
- unsigned h = stoul(sm[4]);
- bool ilace = sm[5].matched ? true : false;
- unsigned refresh = sm[6].matched ? stoul(sm[6]) : 0;
-
- bool found_mode = false;
-
- try {
- output.mode = output.connector->get_mode(w, h, refresh, ilace);
- found_mode = true;
- } catch (exception& e) { }
-
- if (!found_mode && s_use_dmt) {
- try {
- output.mode = find_dmt(w, h, refresh, ilace);
- found_mode = true;
- printf("Found mode from DMT\n");
- } catch (exception& e) { }
- }
-
- if (!found_mode && s_use_cea) {
- try {
- output.mode = find_cea(w, h, refresh, ilace);
- found_mode = true;
- printf("Found mode from CEA\n");
- } catch (exception& e) { }
- }
-
- if (!found_mode)
- throw invalid_argument("Mode not found");
-}
-
-static void parse_plane(Card& card, const string& plane_str, const OutputInfo& output, PlaneInfo& pinfo)
-{
- // 3:400,400-400x400
- const regex plane_re("(?:(@?)(\\d+):)?(?:(\\d+),(\\d+)-)?(\\d+)x(\\d+)");
-
- smatch sm;
- if (!regex_match(plane_str, sm, plane_re))
- EXIT("Failed to parse plane option '%s'", plane_str.c_str());
-
- if (sm[2].matched) {
- bool use_idx = sm[1].length() == 1;
- unsigned num = stoul(sm[2].str());
-
- if (use_idx) {
- auto planes = card.get_planes();
-
- if (num >= planes.size())
- EXIT("Bad plane number '%u'", num);
-
- pinfo.plane = planes[num];
- } else {
- Plane* p = card.get_plane(num);
- if (!p)
- EXIT("Bad plane id '%u'", num);
-
- pinfo.plane = p;
- }
- } else {
- for (Plane* p : output.crtc->get_possible_planes()) {
- if (s_used_planes.find(p) != s_used_planes.end())
- continue;
-
- if (p->plane_type() != PlaneType::Overlay)
- continue;
-
- pinfo.plane = p;
- }
-
- if (!pinfo.plane)
- EXIT("Failed to find available plane");
- }
-
- s_used_planes.insert(pinfo.plane);
-
- pinfo.w = stoul(sm[5]);
- pinfo.h = stoul(sm[6]);
-
- if (sm[3].matched)
- pinfo.x = stoul(sm[3]);
- else
- pinfo.x = output.mode.hdisplay / 2 - pinfo.w / 2;
-
- if (sm[4].matched)
- pinfo.y = stoul(sm[4]);
- else
- pinfo.y = output.mode.vdisplay / 2 - pinfo.h / 2;
-}
-
-static DumbFramebuffer* get_default_fb(Card& card, unsigned width, unsigned height)
-{
- auto fb = new DumbFramebuffer(card, width, height, PixelFormat::XRGB8888);
- draw_test_pattern(*fb);
- return fb;
-}
-
-static DumbFramebuffer* parse_fb(Card& card, const string& fb_str, unsigned def_w, unsigned def_h)
-{
- unsigned w = def_w;
- unsigned h = def_h;
- PixelFormat format = PixelFormat::XRGB8888;
-
- if (!fb_str.empty()) {
- // XXX the regexp is not quite correct
- // 400x400-NV12
- const regex fb_re("(?:(\\d+)x(\\d+))?(?:-)?(\\w\\w\\w\\w)?");
-
- smatch sm;
- if (!regex_match(fb_str, sm, fb_re))
- EXIT("Failed to parse fb option '%s'", fb_str.c_str());
-
- if (sm[1].matched)
- w = stoul(sm[1]);
- if (sm[2].matched)
- h = stoul(sm[2]);
- if (sm[3].matched)
- format = FourCCToPixelFormat(sm[3]);
- }
-
- auto fb = new DumbFramebuffer(card, w, h, format);
- draw_test_pattern(*fb);
- return fb;
-}
-
-static const char* usage_str =
- "Usage: testpat [OPTION]...\n\n"
- "Show a test pattern on a display or plane\n\n"
- "Options:\n"
- " --device=DEVICE DEVICE is the path to DRM card to open\n"
- " -c, --connector=CONN CONN is <connector>\n"
- " -r, --crtc=CRTC CRTC is [<crtc>:]<w>x<h>[@<Hz>]\n"
- " -p, --plane=PLANE PLANE is [<plane>:][<x>,<y>-]<w>x<h>\n"
- " -f, --fb=FB FB is [<w>x<h>][-][<4cc>]\n"
- " --dmt Search for the given mode from DMT tables\n"
- " --cea Search for the given mode from CEA tables\n"
- "\n"
- "<connector>, <crtc> and <plane> can be given by id (<id>) or index (@<idx>).\n"
- "<connector> can also be given by name.\n"
- "\n"
- "Options can be given multiple times to set up multiple displays or planes.\n"
- "Options may apply to previous options, e.g. a plane will be set on a crtc set in\n"
- "an earlier option.\n"
- "If you omit parameters, testpat tries to guess what you mean\n"
- "\n"
- "Examples:\n"
- "\n"
- "Set eDP-1 mode to 1920x1080@60, show XR24 framebuffer on the crtc, and a 400x400 XB24 plane:\n"
- " testpat -c eDP-1 -r 1920x1080@60 -f XR24 -p 400x400 -f XB24\n\n"
- "XR24 framebuffer on first connected connector in the default mode:\n"
- " testpat -f XR24\n\n"
- "XR24 framebuffer on a 400x400 plane on the first connected connector in the default mode:\n"
- " testpat -p 400x400 -f XR24\n\n"
- "Test pattern on the second connector with default mode:\n"
- " testpat -c @1\n"
- ;
-
-static void usage()
-{
- puts(usage_str);
-}
-
-enum class ObjectType
-{
- Connector,
- Crtc,
- Plane,
- Framebuffer,
-};
-
-struct Arg
-{
- ObjectType type;
- string arg;
-};
-
-static string s_device_path = "/dev/dri/card0";
-
-static vector<Arg> parse_cmdline(int argc, char **argv)
-{
- vector<Arg> args;
-
- OptionSet optionset = {
- Option("|device=",
- [&](string s)
- {
- s_device_path = s;
- }),
- Option("c|connector=",
- [&](string s)
- {
- args.push_back(Arg { ObjectType::Connector, s });
- }),
- Option("r|crtc=", [&](string s)
- {
- args.push_back(Arg { ObjectType::Crtc, s });
- }),
- Option("p|plane=", [&](string s)
- {
- args.push_back(Arg { ObjectType::Plane, s });
- }),
- Option("f|fb=", [&](string s)
- {
- args.push_back(Arg { ObjectType::Framebuffer, s });
- }),
- Option("|dmt", []()
- {
- s_use_dmt = true;
- }),
- Option("|cea", []()
- {
- s_use_cea = true;
- }),
- Option("h|help", [&]()
- {
- usage();
- exit(-1);
- }),
- };
-
- optionset.parse(argc, argv);
-
- if (optionset.params().size() > 0) {
- usage();
- exit(-1);
- }
-
- return args;
-}
-
-static vector<OutputInfo> setups_to_outputs(Card& card, const vector<Arg>& output_args)
-{
- vector<OutputInfo> outputs;
-
- if (output_args.size() == 0) {
- // no output args, show a pattern on all screens
- for (auto& pipe : card.get_connected_pipelines()) {
- OutputInfo output = { };
- output.connector = pipe.connector;
- output.crtc = pipe.crtc;
- output.mode = output.connector->get_default_mode();
-
- output.fb = get_default_fb(card, output.mode.hdisplay, output.mode.vdisplay);
-
- outputs.push_back(output);
- }
-
- return outputs;
- }
-
- OutputInfo* current_output = 0;
- PlaneInfo* current_plane = 0;
-
- for (auto& arg : output_args) {
- switch (arg.type) {
- case ObjectType::Connector:
- {
- outputs.push_back(OutputInfo { });
- current_output = &outputs.back();
-
- parse_connector(card, arg.arg, *current_output);
- current_plane = 0;
-
- break;
- }
-
- case ObjectType::Crtc:
- {
- if (!current_output) {
- outputs.push_back(OutputInfo { });
- current_output = &outputs.back();
- }
-
- if (!current_output->connector)
- get_default_connector(card, *current_output);
-
- parse_crtc(card, arg.arg, *current_output);
-
- current_output->user_set_crtc = true;
-
- current_plane = 0;
-
- break;
- }
-
- case ObjectType::Plane:
- {
- if (!current_output) {
- outputs.push_back(OutputInfo { });
- current_output = &outputs.back();
- }
-
- if (!current_output->connector)
- get_default_connector(card, *current_output);
-
- if (!current_output->crtc)
- get_default_crtc(card, *current_output);
-
- current_output->planes.push_back(PlaneInfo { });
- current_plane = &current_output->planes.back();
-
- parse_plane(card, arg.arg, *current_output, *current_plane);
-
- break;
- }
-
- case ObjectType::Framebuffer:
- {
- if (!current_output) {
- outputs.push_back(OutputInfo { });
- current_output = &outputs.back();
- }
-
- if (!current_output->connector)
- get_default_connector(card, *current_output);
-
- if (!current_output->crtc)
- get_default_crtc(card, *current_output);
-
- int def_w, def_h;
-
- if (current_plane) {
- def_w = current_plane->w;
- def_h = current_plane->h;
- } else {
- def_w = current_output->mode.hdisplay;
- def_h = current_output->mode.vdisplay;
- }
-
- auto fb = parse_fb(card, arg.arg, def_w, def_h);
-
- if (current_plane)
- current_plane->fb = fb;
- else
- current_output->fb = fb;
-
- break;
- }
- }
- }
-
- // create default framebuffers if needed
- for (OutputInfo& o : outputs) {
- if (!o.crtc) {
- get_default_crtc(card, *current_output);
- o.user_set_crtc = true;
- }
-
- if (!o.fb && o.user_set_crtc)
- o.fb = get_default_fb(card, o.mode.hdisplay, o.mode.vdisplay);
-
- for (PlaneInfo &p : o.planes) {
- if (!p.fb)
- p.fb = get_default_fb(card, p.w, p.h);
- }
- }
-
- return outputs;
-}
-
-static std::string videomode_to_string(const Videomode& mode)
-{
- unsigned hfp = mode.hsync_start - mode.hdisplay;
- unsigned hsw = mode.hsync_end - mode.hsync_start;
- unsigned hbp = mode.htotal - mode.hsync_end;
-
- unsigned vfp = mode.vsync_start - mode.vdisplay;
- unsigned vsw = mode.vsync_end - mode.vsync_start;
- unsigned vbp = mode.vtotal - mode.vsync_end;
-
- float hz = (mode.clock * 1000.0) / (mode.htotal * mode.vtotal);
- if (mode.flags & (1<<4)) // XXX interlace
- hz *= 2;
-
- char buf[256];
-
- sprintf(buf, "%.2f MHz %u/%u/%u/%u %u/%u/%u/%u %uHz (%.2fHz)",
- mode.clock / 1000.0,
- mode.hdisplay, hfp, hsw, hbp,
- mode.vdisplay, vfp, vsw, vbp,
- mode.vrefresh, hz);
-
- return std::string(buf);
-}
-
-static void print_outputs(const vector<OutputInfo>& outputs)
-{
- for (unsigned i = 0; i < outputs.size(); ++i) {
- const OutputInfo& o = outputs[i];
-
- printf("Connector %u/@%u: %s\n", o.connector->id(), o.connector->idx(),
- o.connector->fullname().c_str());
- printf(" Crtc %u/@%u: %ux%u-%u (%s)\n", o.crtc->id(), o.crtc->idx(),
- o.mode.hdisplay, o.mode.vdisplay, o.mode.vrefresh,
- videomode_to_string(o.mode).c_str());
- if (o.fb)
- printf(" Fb %ux%u-%s\n", o.fb->width(), o.fb->height(),
- PixelFormatToFourCC(o.fb->format()).c_str());
-
- for (unsigned j = 0; j < o.planes.size(); ++j) {
- const PlaneInfo& p = o.planes[j];
- printf(" Plane %u/@%u: %u,%u-%ux%u\n", p.plane->id(), p.plane->idx(),
- p.x, p.y, p.w, p.h);
- printf(" Fb %ux%u-%s\n", p.fb->width(), p.fb->height(),
- PixelFormatToFourCC(p.fb->format()).c_str());
- }
- }
-}
-
-static void set_crtcs_n_planes(Card& card, const vector<OutputInfo>& outputs)
-{
- for (const OutputInfo& o : outputs) {
- auto conn = o.connector;
- auto crtc = o.crtc;
-
- if (o.fb) {
- int r = crtc->set_mode(conn, *o.fb, o.mode);
- if (r)
- printf("crtc->set_mode() failed for crtc %u: %s\n",
- crtc->id(), strerror(-r));
- }
-
- for (const PlaneInfo& p : o.planes) {
- int r = crtc->set_plane(p.plane, *p.fb,
- p.x, p.y, p.w, p.h,
- 0, 0, p.fb->width(), p.fb->height());
- if (r)
- printf("crtc->set_plane() failed for plane %u: %s\n",
- p.plane->id(), strerror(-r));
- }
- }
-}
-
-int main(int argc, char **argv)
-{
- vector<Arg> output_args = parse_cmdline(argc, argv);
-
- Card card(s_device_path);
-
- vector<OutputInfo> outputs = setups_to_outputs(card, output_args);
-
- print_outputs(outputs);
-
- set_crtcs_n_planes(card, outputs);
-
- printf("press enter to exit\n");
-
- getchar();
-}