diff options
author | Tomi Valkeinen <tomi.valkeinen@ti.com> | 2016-05-23 09:54:08 +0300 |
---|---|---|
committer | Tomi Valkeinen <tomi.valkeinen@ti.com> | 2016-05-23 09:54:08 +0300 |
commit | a5c28bcb2ead34e921617711ebf94ffcb5d72878 (patch) | |
tree | e2f93259f63407357c70b06a7d59c24fde5a3901 /tests | |
parent | 0bc5bbd6766949d651f98e12981d79c86ce0bf99 (diff) |
File/dir renames
Diffstat (limited to 'tests')
-rw-r--r-- | tests/CMakeLists.txt | 20 | ||||
-rw-r--r-- | tests/db.cpp | 265 | ||||
-rw-r--r-- | tests/fbtestpat.cpp | 60 | ||||
-rw-r--r-- | tests/kmscapture.cpp | 435 | ||||
-rw-r--r-- | tests/kmsprint.cpp | 221 | ||||
-rw-r--r-- | tests/kmsview.cpp | 92 | ||||
-rw-r--r-- | tests/testpat.cpp | 604 |
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 = ¤t_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(); -} |