summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--kms++/CMakeLists.txt13
-rw-r--r--kms++/inc/kms++/atomicreq.h3
-rw-r--r--kms++/inc/kms++/connector.h2
-rw-r--r--kms++/inc/kms++/modedb.h4
-rw-r--r--kms++/inc/kms++/videomode.h3
-rw-r--r--kms++/src/atomicreq.cpp25
-rw-r--r--kms++/src/connector.cpp11
-rw-r--r--kms++/src/modedb.cpp15
-rw-r--r--kms++/src/modedb_cea.cpp3
-rw-r--r--kms++/src/modedb_dmt.cpp4
-rw-r--r--kms++/src/videomode.cpp10
-rw-r--r--kms++util/CMakeLists.txt13
-rw-r--r--kms++util/inc/kms++util/extcpuframebuffer.h7
-rw-r--r--kms++util/inc/kms++util/resourcemanager.h1
-rw-r--r--kms++util/src/extcpuframebuffer.cpp12
-rw-r--r--py/CMakeLists.txt3
-rw-r--r--py/pykmsbase.cpp2
-rw-r--r--utils/CMakeLists.txt3
-rw-r--r--utils/fbtestpat.cpp6
-rw-r--r--utils/kmsprint.cpp14
-rw-r--r--utils/testpat.cpp49
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());