diff options
-rw-r--r-- | kms++/CMakeLists.txt | 13 | ||||
-rw-r--r-- | kms++/inc/kms++/atomicreq.h | 3 | ||||
-rw-r--r-- | kms++/inc/kms++/connector.h | 2 | ||||
-rw-r--r-- | kms++/inc/kms++/modedb.h | 4 | ||||
-rw-r--r-- | kms++/inc/kms++/videomode.h | 3 | ||||
-rw-r--r-- | kms++/src/atomicreq.cpp | 25 | ||||
-rw-r--r-- | kms++/src/connector.cpp | 11 | ||||
-rw-r--r-- | kms++/src/modedb.cpp | 15 | ||||
-rw-r--r-- | kms++/src/modedb_cea.cpp | 3 | ||||
-rw-r--r-- | kms++/src/modedb_dmt.cpp | 4 | ||||
-rw-r--r-- | kms++/src/videomode.cpp | 10 | ||||
-rw-r--r-- | kms++util/CMakeLists.txt | 13 | ||||
-rw-r--r-- | kms++util/inc/kms++util/extcpuframebuffer.h | 7 | ||||
-rw-r--r-- | kms++util/inc/kms++util/resourcemanager.h | 1 | ||||
-rw-r--r-- | kms++util/src/extcpuframebuffer.cpp | 12 | ||||
-rw-r--r-- | py/CMakeLists.txt | 3 | ||||
-rw-r--r-- | py/pykmsbase.cpp | 2 | ||||
-rw-r--r-- | utils/CMakeLists.txt | 3 | ||||
-rw-r--r-- | utils/fbtestpat.cpp | 6 | ||||
-rw-r--r-- | utils/kmsprint.cpp | 14 | ||||
-rw-r--r-- | utils/testpat.cpp | 49 |
21 files changed, 129 insertions, 74 deletions
diff --git a/kms++/CMakeLists.txt b/kms++/CMakeLists.txt index d983964..51ccc65 100644 --- a/kms++/CMakeLists.txt +++ b/kms++/CMakeLists.txt @@ -1,8 +1,9 @@ include_directories(${LIBDRM_INCLUDE_DIRS}) link_directories(${LIBDRM_LIBRARY_DIRS}) -file(GLOB SRCS "src/*.cpp" "src/*.h" "inc/kms++/*.h") -add_library(kms++ ${SRCS}) +file(GLOB SRCS "src/*.cpp" "src/*.h") +file(GLOB PUB_HDRS "inc/kms++/*.h") +add_library(kms++ ${SRCS} ${PUB_HDRS}) target_include_directories(kms++ PUBLIC $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/inc> @@ -10,3 +11,11 @@ target_include_directories(kms++ PUBLIC PRIVATE src) target_link_libraries(kms++ ${LIBDRM_LIBRARIES}) + +set_target_properties(kms++ PROPERTIES + PUBLIC_HEADER "${PUB_HDRS}") + +install(TARGETS kms++ + LIBRARY DESTINATION lib + ARCHIVE DESTINATION lib + PUBLIC_HEADER DESTINATION include/kms++) diff --git a/kms++/inc/kms++/atomicreq.h b/kms++/inc/kms++/atomicreq.h index a9f779d..a678b54 100644 --- a/kms++/inc/kms++/atomicreq.h +++ b/kms++/inc/kms++/atomicreq.h @@ -24,6 +24,9 @@ public: void add(DrmPropObject *ob, const std::string& prop, uint64_t value); void add(DrmPropObject *ob, const std::map<std::string, uint64_t>& values); + void add_display(Connector* conn, Crtc* crtc, Blob* videomode, + Plane* primary, Framebuffer* fb); + int test(bool allow_modeset = false); int commit(void* data, bool allow_modeset = false); int commit_sync(bool allow_modeset = false); diff --git a/kms++/inc/kms++/connector.h b/kms++/inc/kms++/connector.h index 6ccc959..ccd7728 100644 --- a/kms++/inc/kms++/connector.h +++ b/kms++/inc/kms++/connector.h @@ -17,7 +17,7 @@ public: Videomode get_default_mode() const; Videomode get_mode(const std::string& mode) const; - Videomode get_mode(unsigned xres, unsigned yres, unsigned refresh, bool ilace) const; + Videomode get_mode(unsigned xres, unsigned yres, float vrefresh, bool ilace) const; Crtc* get_current_crtc() const; std::vector<Crtc*> get_possible_crtcs() const; diff --git a/kms++/inc/kms++/modedb.h b/kms++/inc/kms++/modedb.h index 43c7afc..b6447c6 100644 --- a/kms++/inc/kms++/modedb.h +++ b/kms++/inc/kms++/modedb.h @@ -10,7 +10,7 @@ struct Videomode; extern const Videomode dmt_modes[]; extern const Videomode cea_modes[]; -const Videomode& find_dmt(uint32_t width, uint32_t height, uint32_t vrefresh, bool ilace); -const Videomode& find_cea(uint32_t width, uint32_t height, uint32_t refresh, bool ilace); +const Videomode& find_dmt(uint32_t width, uint32_t height, float vrefresh, bool ilace); +const Videomode& find_cea(uint32_t width, uint32_t height, float vrefresh, bool ilace); } diff --git a/kms++/inc/kms++/videomode.h b/kms++/inc/kms++/videomode.h index f9abaf9..ec16969 100644 --- a/kms++/inc/kms++/videomode.h +++ b/kms++/inc/kms++/videomode.h @@ -31,6 +31,9 @@ struct Videomode uint16_t vfp() const { return vsync_start - vdisplay; } uint16_t vsw() const { return vsync_end - vsync_start; } uint16_t vbp() const { return vtotal - vsync_end; } + + bool interlace() const; + float calculated_vrefresh() const; }; } diff --git a/kms++/src/atomicreq.cpp b/kms++/src/atomicreq.cpp index f2809af..28128f2 100644 --- a/kms++/src/atomicreq.cpp +++ b/kms++/src/atomicreq.cpp @@ -60,6 +60,31 @@ void AtomicReq::add(kms::DrmPropObject* ob, const map<string, uint64_t>& values) add(ob, kvp.first, kvp.second); } +void AtomicReq::add_display(Connector* conn, Crtc* crtc, Blob* videomode, Plane* primary, Framebuffer* fb) +{ + add(conn, { + { "CRTC_ID", crtc->id() }, + }); + + add(crtc, { + { "ACTIVE", 1 }, + { "MODE_ID", videomode->id() }, + }); + + add(primary, { + { "FB_ID", fb->id() }, + { "CRTC_ID", crtc->id() }, + { "SRC_X", 0 << 16 }, + { "SRC_Y", 0 << 16 }, + { "SRC_W", fb->width() << 16 }, + { "SRC_H", fb->height() << 16 }, + { "CRTC_X", 0 }, + { "CRTC_Y", 0 }, + { "CRTC_W", fb->width() }, + { "CRTC_H", fb->height() }, + }); +} + int AtomicReq::test(bool allow_modeset) { uint32_t flags = DRM_MODE_ATOMIC_TEST_ONLY; diff --git a/kms++/src/connector.cpp b/kms++/src/connector.cpp index ec37d5d..92700af 100644 --- a/kms++/src/connector.cpp +++ b/kms++/src/connector.cpp @@ -3,6 +3,7 @@ #include <unistd.h> #include <fcntl.h> #include <cassert> +#include <cmath> #include <kms++/kms++.h> #include "helpers.h" @@ -118,23 +119,23 @@ Videomode Connector::get_mode(const string& mode) const throw invalid_argument(mode + ": mode not found"); } -Videomode Connector::get_mode(unsigned xres, unsigned yres, unsigned refresh, bool ilace) const +Videomode Connector::get_mode(unsigned xres, unsigned yres, float vrefresh, bool ilace) const { auto c = m_priv->drm_connector; for (int i = 0; i < c->count_modes; i++) { - drmModeModeInfo& m = c->modes[i]; + Videomode m = drm_mode_to_video_mode(c->modes[i]); if (m.hdisplay != xres || m.vdisplay != yres) continue; - if (refresh && m.vrefresh != refresh) + if (ilace != m.interlace()) continue; - if (ilace != !!(m.flags & DRM_MODE_FLAG_INTERLACE)) + if (vrefresh && std::abs(m.calculated_vrefresh() - vrefresh) >= 0.001) continue; - return drm_mode_to_video_mode(c->modes[i]); + return m; } throw invalid_argument("mode not found"); diff --git a/kms++/src/modedb.cpp b/kms++/src/modedb.cpp index 24d6f63..858c3d0 100644 --- a/kms++/src/modedb.cpp +++ b/kms++/src/modedb.cpp @@ -1,5 +1,6 @@ #include <xf86drm.h> #include <stdexcept> +#include <cmath> #include <kms++/modedb.h> @@ -8,7 +9,7 @@ using namespace std; namespace kms { -static const Videomode& find_from_table(const Videomode* modes, uint32_t width, uint32_t height, uint32_t refresh, bool ilace) +static const Videomode& find_from_table(const Videomode* modes, uint32_t width, uint32_t height, float vrefresh, bool ilace) { for (unsigned i = 0; modes[i].clock; ++i) { const Videomode& m = modes[i]; @@ -16,10 +17,10 @@ static const Videomode& find_from_table(const Videomode* modes, uint32_t width, if (m.hdisplay != width || m.vdisplay != height) continue; - if (refresh && m.vrefresh != refresh) + if (ilace != m.interlace()) continue; - if (ilace != !!(m.flags & DRM_MODE_FLAG_INTERLACE)) + if (vrefresh && std::abs(m.calculated_vrefresh() - vrefresh) >= 0.001) continue; return m; @@ -28,14 +29,14 @@ static const Videomode& find_from_table(const Videomode* modes, uint32_t width, throw invalid_argument("mode not found"); } -const Videomode& find_dmt(uint32_t width, uint32_t height, uint32_t refresh, bool ilace) +const Videomode& find_dmt(uint32_t width, uint32_t height, float vrefresh, bool ilace) { - return find_from_table(dmt_modes, width, height, refresh, ilace); + return find_from_table(dmt_modes, width, height, vrefresh, ilace); } -const Videomode& find_cea(uint32_t width, uint32_t height, uint32_t refresh, bool ilace) +const Videomode& find_cea(uint32_t width, uint32_t height, float vrefresh, bool ilace) { - return find_from_table(cea_modes, width, height, refresh, ilace); + return find_from_table(cea_modes, width, height, vrefresh, ilace); } } diff --git a/kms++/src/modedb_cea.cpp b/kms++/src/modedb_cea.cpp index a105dd8..a99a612 100644 --- a/kms++/src/modedb_cea.cpp +++ b/kms++/src/modedb_cea.cpp @@ -42,7 +42,8 @@ namespace kms .name = nm, .clock = (c), \ .hdisplay = (hd), .hsync_start = (hss), .hsync_end = (hse), .htotal = (ht), .hskew = (hsk), \ .vdisplay = (vd), .vsync_start = (vss), .vsync_end = (vse), .vtotal = (vt), .vscan = (vs), \ - .vrefresh = DIV_ROUND(c * 1000, ht * vt), .flags = (f), .type = 0 + .vrefresh = DIV_ROUND(c * 1000, ht * vt) * (((f) & DRM_MODE_FLAG_INTERLACE) ? 2 : 1), \ + .flags = (f), .type = 0 /* * Probably taken from CEA-861 spec. diff --git a/kms++/src/modedb_dmt.cpp b/kms++/src/modedb_dmt.cpp index e3f2ad5..c3d5426 100644 --- a/kms++/src/modedb_dmt.cpp +++ b/kms++/src/modedb_dmt.cpp @@ -42,8 +42,8 @@ namespace kms .name = nm, .clock = (c), \ .hdisplay = (hd), .hsync_start = (hss), .hsync_end = (hse), .htotal = (ht), .hskew = (hsk), \ .vdisplay = (vd), .vsync_start = (vss), .vsync_end = (vse), .vtotal = (vt), .vscan = (vs), \ - .vrefresh = DIV_ROUND(c * 1000, ht * vt), .flags = (f), .type = 0 - + .vrefresh = DIV_ROUND(c * 1000, ht * vt) * (((f) & DRM_MODE_FLAG_INTERLACE) ? 2 : 1), \ + .flags = (f), .type = 0 /* * Autogenerated from the DMT spec. diff --git a/kms++/src/videomode.cpp b/kms++/src/videomode.cpp index 30d47f8..16330bb 100644 --- a/kms++/src/videomode.cpp +++ b/kms++/src/videomode.cpp @@ -16,4 +16,14 @@ unique_ptr<Blob> Videomode::to_blob(Card& card) const return unique_ptr<Blob>(new Blob(card, &drm_mode, sizeof(drm_mode))); } +bool Videomode::interlace() const +{ + return flags & DRM_MODE_FLAG_INTERLACE; +} + +float Videomode::calculated_vrefresh() const +{ + return (clock * 1000.0) / (htotal * vtotal) * (interlace() ? 2 : 1); +} + } diff --git a/kms++util/CMakeLists.txt b/kms++util/CMakeLists.txt index 3977f70..2fc15e3 100644 --- a/kms++util/CMakeLists.txt +++ b/kms++util/CMakeLists.txt @@ -1,5 +1,6 @@ -file(GLOB SRCS "src/*.cpp" "src/*.h" "inc/kms++util/*.h") -add_library(kms++util ${SRCS}) +file(GLOB SRCS "src/*.cpp" "src/*.h") +file(GLOB PUB_HDRS "inc/kms++util/*.h") +add_library(kms++util ${SRCS} ${PUB_HDRS}) target_include_directories(kms++util PUBLIC $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/inc> @@ -7,3 +8,11 @@ target_include_directories(kms++util PUBLIC PRIVATE src) target_link_libraries(kms++util kms++ pthread) + +set_target_properties(kms++util PROPERTIES + PUBLIC_HEADER "${PUB_HDRS}") + +install(TARGETS kms++util + LIBRARY DESTINATION lib + ARCHIVE DESTINATION lib + PUBLIC_HEADER DESTINATION include/kms++util) diff --git a/kms++util/inc/kms++util/extcpuframebuffer.h b/kms++util/inc/kms++util/extcpuframebuffer.h index 5d3be74..3652ec4 100644 --- a/kms++util/inc/kms++util/extcpuframebuffer.h +++ b/kms++util/inc/kms++util/extcpuframebuffer.h @@ -9,9 +9,9 @@ class ExtCPUFramebuffer : public IMappedFramebuffer { public: ExtCPUFramebuffer(uint32_t width, uint32_t height, PixelFormat format, - uint8_t* buffer, uint32_t pitch); + uint8_t* buffer, uint32_t size, uint32_t pitch, uint32_t offset); ExtCPUFramebuffer(uint32_t width, uint32_t height, PixelFormat format, - uint8_t* buffers[4], uint32_t pitches[4]); + uint8_t* buffers[4], uint32_t sizes[4], uint32_t pitches[4], uint32_t offsets[4]); virtual ~ExtCPUFramebuffer(); uint32_t width() const { return m_width; } @@ -22,13 +22,14 @@ public: uint32_t stride(unsigned plane) const { return m_planes[plane].stride; } uint32_t size(unsigned plane) const { return m_planes[plane].size; } - uint32_t offset(unsigned plane) const { return 0; } + uint32_t offset(unsigned plane) const { return m_planes[plane].offset; } uint8_t* map(unsigned plane) { return m_planes[plane].map; } private: struct FramebufferPlane { uint32_t size; uint32_t stride; + uint32_t offset; uint8_t *map; }; diff --git a/kms++util/inc/kms++util/resourcemanager.h b/kms++util/inc/kms++util/resourcemanager.h index 92e7b93..42e5000 100644 --- a/kms++util/inc/kms++util/resourcemanager.h +++ b/kms++util/inc/kms++util/resourcemanager.h @@ -11,6 +11,7 @@ public: void reset(); + Card& card() const { return m_card; } Connector* reserve_connector(const std::string& name = ""); Crtc* reserve_crtc(Connector* conn); Plane* reserve_plane(Crtc* crtc, PlaneType type, PixelFormat format = PixelFormat::Undefined); diff --git a/kms++util/src/extcpuframebuffer.cpp b/kms++util/src/extcpuframebuffer.cpp index 232c778..feb3add 100644 --- a/kms++util/src/extcpuframebuffer.cpp +++ b/kms++util/src/extcpuframebuffer.cpp @@ -7,7 +7,7 @@ namespace kms { ExtCPUFramebuffer::ExtCPUFramebuffer(uint32_t width, uint32_t height, PixelFormat format, - uint8_t* buffer, uint32_t pitch) + uint8_t* buffer, uint32_t size, uint32_t pitch, uint32_t offset) : m_width(width), m_height(height), m_format(format) { const PixelFormatInfo& format_info = get_pixel_format_info(m_format); @@ -16,16 +16,16 @@ ExtCPUFramebuffer::ExtCPUFramebuffer(uint32_t width, uint32_t height, PixelForma ASSERT(m_num_planes == 1); - const PixelFormatPlaneInfo& pi = format_info.planes[0]; FramebufferPlane& plane = m_planes[0]; plane.stride = pitch; - plane.size = plane.stride * height / pi.ysub; + plane.size = size; + plane.offset = offset; plane.map = buffer; } ExtCPUFramebuffer::ExtCPUFramebuffer(uint32_t width, uint32_t height, PixelFormat format, - uint8_t* buffers[4], uint32_t pitches[4]) + uint8_t* buffers[4], uint32_t sizes[4], uint32_t pitches[4], uint32_t offsets[4]) : m_width(width), m_height(height), m_format(format) { const PixelFormatInfo& format_info = get_pixel_format_info(m_format); @@ -33,11 +33,11 @@ ExtCPUFramebuffer::ExtCPUFramebuffer(uint32_t width, uint32_t height, PixelForma m_num_planes = format_info.num_planes; for (unsigned i = 0; i < format_info.num_planes; ++i) { - const PixelFormatPlaneInfo& pi = format_info.planes[i]; FramebufferPlane& plane = m_planes[i]; plane.stride = pitches[i]; - plane.size = plane.stride * height / pi.ysub; + plane.size = sizes[i]; + plane.offset = offsets[i]; plane.map = buffers[i]; } } diff --git a/py/CMakeLists.txt b/py/CMakeLists.txt index 1349ea5..0cb4b99 100644 --- a/py/CMakeLists.txt +++ b/py/CMakeLists.txt @@ -23,3 +23,6 @@ add_test(NAME pytest COMMAND "${CMAKE_CURRENT_SOURCE_DIR}/functest.py") set_property(TEST pytest PROPERTY ENVIRONMENT "PYTHONPATH=." "LD_LIBRARY_PATH=." ) + +# XXX Where should pykms.so be installed? +#install(TARGETS pykms DESTINATION lib) diff --git a/py/pykmsbase.cpp b/py/pykmsbase.cpp index 637e4f5..3ce5676 100644 --- a/py/pykmsbase.cpp +++ b/py/pykmsbase.cpp @@ -42,7 +42,7 @@ void init_pykmsbase(py::module &m) .def("get_possible_crtcs", &Connector::get_possible_crtcs) .def("get_modes", &Connector::get_modes) .def("get_mode", (Videomode (Connector::*)(const string& mode) const)&Connector::get_mode) - .def("get_mode", (Videomode (Connector::*)(unsigned xres, unsigned yres, unsigned refresh, bool ilace) const)&Connector::get_mode) + .def("get_mode", (Videomode (Connector::*)(unsigned xres, unsigned yres, float refresh, bool ilace) const)&Connector::get_mode) .def("__repr__", [](const Connector& o) { return "<pykms.Connector " + to_string(o.id()) + ">"; }) ; diff --git a/utils/CMakeLists.txt b/utils/CMakeLists.txt index dd95f70..0b15481 100644 --- a/utils/CMakeLists.txt +++ b/utils/CMakeLists.txt @@ -24,3 +24,6 @@ target_link_libraries(wbcap kms++ kms++util ${LIBDRM_LIBRARIES}) add_executable (wbm2m wbm2m.cpp) target_link_libraries(wbm2m kms++ kms++util ${LIBDRM_LIBRARIES}) + +install(TARGETS testpat kmsprint fbtestpat + DESTINATION bin) diff --git a/utils/fbtestpat.cpp b/utils/fbtestpat.cpp index 4fe0d41..1c9a5f1 100644 --- a/utils/fbtestpat.cpp +++ b/utils/fbtestpat.cpp @@ -40,7 +40,8 @@ int main(int argc, char** argv) FAIL_IF(ptr == MAP_FAILED, "mmap failed"); - ExtCPUFramebuffer buf(var.xres, var.yres_virtual, PixelFormat::XRGB8888, ptr, fix.line_length); + ExtCPUFramebuffer buf(var.xres, var.yres, PixelFormat::XRGB8888, + ptr, var.yres_virtual * fix.line_length, fix.line_length, 0); printf("%s: res %dx%d, virtual %dx%d, line_len %d\n", fbdev, @@ -51,9 +52,6 @@ int main(int argc, char** argv) draw_test_pattern(buf); draw_text(buf, buf.width() / 2, 0, fbdev, RGB(255, 255, 255)); - 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/utils/kmsprint.cpp b/utils/kmsprint.cpp index fe1280e..e6a4be4 100644 --- a/utils/kmsprint.cpp +++ b/utils/kmsprint.cpp @@ -25,7 +25,7 @@ static string format_mode(const Videomode& m, unsigned idx) str = sformat(" %2u ", idx); if (s_opts.x_modeline) { - str += sformat("%12s %6d %4u %4u %4u %4u %4u %4u %4u %4u %2u %#x %#x", + str += sformat("%12s %6u %4u %4u %4u %4u %4u %4u %4u %4u %2u %#x %#x", m.name.c_str(), m.clock, m.hdisplay, m.hsync_start, m.hsync_end, m.htotal, @@ -37,11 +37,11 @@ static string format_mode(const Videomode& m, unsigned idx) string h = sformat("%u/%u/%u/%u", m.hdisplay, m.hfp(), m.hsw(), m.hbp()); string v = sformat("%u/%u/%u/%u", m.vdisplay, m.vfp(), m.vsw(), m.vbp()); - str += sformat("%-12s %6d %-16s %-16s %2u %#10x %#6x", + str += sformat("%-12s %7.3f %-16s %-16s %2u (%.2f) %#10x %#6x", m.name.c_str(), - m.clock, + m.clock / 1000.0, h.c_str(), v.c_str(), - m.vrefresh, + m.vrefresh, m.calculated_vrefresh(), m.flags, m.type); } @@ -54,11 +54,11 @@ static string format_mode_short(const Videomode& m) string h = sformat("%u/%u/%u/%u", m.hdisplay, m.hfp(), m.hsw(), m.hbp()); string v = sformat("%u/%u/%u/%u", m.vdisplay, m.vfp(), m.vsw(), m.vbp()); - return sformat("%s %d %s %s %u", + return sformat("%s %.3f %s %s %u (%.2f)", m.name.c_str(), - m.clock, + m.clock / 1000.0, h.c_str(), v.c_str(), - m.vrefresh); + m.vrefresh, m.calculated_vrefresh()); } static string format_connector(Connector& c) diff --git a/utils/testpat.cpp b/utils/testpat.cpp index 7208105..ccddccb 100644 --- a/utils/testpat.cpp +++ b/utils/testpat.cpp @@ -102,7 +102,7 @@ static void get_default_crtc(Card& card, OutputInfo& output) 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+))?"); + const regex mode_re("(?:(@?)(\\d+):)?(?:(\\d+)x(\\d+)(i)?)(?:@([\\d\\.]+))?"); smatch sm; if (!regex_match(crtc_str, sm, mode_re)) @@ -133,7 +133,7 @@ static void parse_crtc(Card& card, const string& crtc_str, OutputInfo& output) 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; + float refresh = sm[6].matched ? stof(sm[6]) : 0; bool found_mode = false; @@ -507,29 +507,18 @@ static vector<OutputInfo> setups_to_outputs(Card& card, const vector<Arg>& outpu return outputs; } -static std::string videomode_to_string(const Videomode& mode) +static std::string videomode_to_string(const Videomode& m) { - 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); + string h = sformat("%u/%u/%u/%u", m.hdisplay, m.hfp(), m.hsw(), m.hbp()); + string v = sformat("%u/%u/%u/%u", m.vdisplay, m.vfp(), m.vsw(), m.vbp()); + + return sformat("%s %.3f %s %s %u (%.2f) %#x %#x", + m.name.c_str(), + m.clock / 1000.0, + h.c_str(), v.c_str(), + m.vrefresh, m.calculated_vrefresh(), + m.flags, + m.type); } static void print_outputs(const vector<OutputInfo>& outputs) @@ -537,14 +526,12 @@ 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(), + printf("Connector %u/@%u: %s\n", o.connector->idx(), o.connector->id(), o.connector->fullname().c_str()); - printf(" Crtc %u/@%u", o.crtc->id(), o.crtc->idx()); + printf(" Crtc %u/@%u", o.crtc->idx(), o.crtc->id()); if (o.primary_plane) - printf(" (plane %u/@%u)", o.primary_plane->id(), o.primary_plane->idx()); - printf(": %ux%u-%u (%s)\n", - o.mode.hdisplay, o.mode.vdisplay, o.mode.vrefresh, - videomode_to_string(o.mode).c_str()); + printf(" (plane %u/@%u)", o.primary_plane->idx(), o.primary_plane->id()); + printf(": %s\n", videomode_to_string(o.mode).c_str()); if (!o.fbs.empty()) { auto fb = o.fbs[0]; printf(" Fb %u %ux%u-%s\n", fb->id(), fb->width(), fb->height(), @@ -554,7 +541,7 @@ static void print_outputs(const vector<OutputInfo>& outputs) for (unsigned j = 0; j < o.planes.size(); ++j) { const PlaneInfo& p = o.planes[j]; auto fb = p.fbs[0]; - printf(" Plane %u/@%u: %u,%u-%ux%u\n", p.plane->id(), p.plane->idx(), + printf(" Plane %u/@%u: %u,%u-%ux%u\n", p.plane->idx(), p.plane->id(), p.x, p.y, p.w, p.h); printf(" Fb %u %ux%u-%s\n", fb->id(), fb->width(), fb->height(), PixelFormatToFourCC(fb->format()).c_str()); |