summaryrefslogtreecommitdiff
path: root/kms++
diff options
context:
space:
mode:
Diffstat (limited to 'kms++')
-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
11 files changed, 73 insertions, 20 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);
+}
+
}