aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTomi Valkeinen2017-11-24 01:50:42 -0600
committerTomi Valkeinen2017-11-24 02:05:01 -0600
commit706a44abb3aa7b4535ded7d5c934147b7de06ed1 (patch)
tree41e0b10413ab6d24fdfeeaa6a28c3f335c7198c3
parent75e85e48c35f9e18a974af1c1e973d9482ed1fc4 (diff)
downloadexternal-libkmsxx-706a44abb3aa7b4535ded7d5c934147b7de06ed1.tar.gz
external-libkmsxx-706a44abb3aa7b4535ded7d5c934147b7de06ed1.tar.xz
external-libkmsxx-706a44abb3aa7b4535ded7d5c934147b7de06ed1.zip
Update to latest pybind11
Update to latest pybind11 HEAD. We can't use the latest tag (v2.2.0) as it has a regression. There were two problems when updating: 1) Difficulty in managing DrmObject derived classes Most of the DrmObjects are owned by Card, and can't be allocated or freed, but a few of them are allocated and freed by the user. For the former, we need to use unique_ptr with py::nodelete, but that prevents the latter from working. The solution was to not tell the python that the latter classes derive from DrmObject. This seems to be missing feature in pybind11, but I think we can live with it. 2) DrmObjects in STL containers vector<T> where T is a DrmObject derived class doesn't work. We need to have a manual wrapper to return vector<unique_ptr<T, py::nodelete>> instead. This also seems to be a pybind11 missing feature. Signed-off-by: Tomi Valkeinen <tomi.valkeinen@ti.com>
m---------ext/pybind110
-rw-r--r--py/pykms/pykms.cpp5
-rw-r--r--py/pykms/pykmsbase.cpp63
-rw-r--r--py/pykms/pykmsomap.cpp4
-rw-r--r--py/pykms/pyvid.cpp4
5 files changed, 50 insertions, 26 deletions
diff --git a/ext/pybind11 b/ext/pybind11
Subproject e70b2abb6dee27a2889b01f245a2a28e6fcd4b0 Subproject 086d53e8c66a84d0ec723d5435918c76edd878e
diff --git a/py/pykms/pykms.cpp b/py/pykms/pykms.cpp
index 1e54c9b..fec8417 100644
--- a/py/pykms/pykms.cpp
+++ b/py/pykms/pykms.cpp
@@ -15,9 +15,7 @@ void init_pyvid(py::module &m);
15void init_pykmsomap(py::module &m); 15void init_pykmsomap(py::module &m);
16#endif 16#endif
17 17
18PYBIND11_PLUGIN(pykms) { 18PYBIND11_MODULE(pykms, m) {
19 py::module m("pykms", "kms bindings");
20
21 init_pykmsbase(m); 19 init_pykmsbase(m);
22 20
23 init_pykmstest(m); 21 init_pykmstest(m);
@@ -27,5 +25,4 @@ PYBIND11_PLUGIN(pykms) {
27#if HAS_LIBDRM_OMAP 25#if HAS_LIBDRM_OMAP
28 init_pykmsomap(m); 26 init_pykmsomap(m);
29#endif 27#endif
30 return m.ptr();
31} 28}
diff --git a/py/pykms/pykmsbase.cpp b/py/pykms/pykmsbase.cpp
index fe4bc46..aae5ece 100644
--- a/py/pykms/pykmsbase.cpp
+++ b/py/pykms/pykmsbase.cpp
@@ -12,22 +12,36 @@ void init_pykmsbase(py::module &m)
12 py::class_<Card>(m, "Card") 12 py::class_<Card>(m, "Card")
13 .def(py::init<>()) 13 .def(py::init<>())
14 .def_property_readonly("fd", &Card::fd) 14 .def_property_readonly("fd", &Card::fd)
15 .def("get_first_connected_connector", &Card::get_first_connected_connector) 15 .def_property_readonly("get_first_connected_connector", &Card::get_first_connected_connector)
16 .def_property_readonly("connectors", &Card::get_connectors) 16
17 .def_property_readonly("crtcs", &Card::get_crtcs) 17 // XXX pybind11 can't handle vector<T*> where T is non-copyable, and complains:
18 .def_property_readonly("encoders", &Card::get_encoders) 18 // RuntimeError: return_value_policy = move, but the object is neither movable nor copyable!
19 .def_property_readonly("planes", &Card::get_planes) 19 // So we do this manually.
20 .def_property_readonly("connectors", [](Card* self) {
21 vector<unique_ptr<Connector, py::nodelete>> v;
22 for (Connector* p : self->get_connectors())
23 v.push_back(unique_ptr<Connector, py::nodelete>(p));
24 return v;
25 })
26
27 .def_property_readonly("planes", [](Card* self) {
28 vector<unique_ptr<Plane, py::nodelete>> v;
29 for (Plane* p : self->get_planes())
30 v.push_back(unique_ptr<Plane, py::nodelete>(p));
31 return v;
32 })
33
20 .def_property_readonly("has_atomic", &Card::has_atomic) 34 .def_property_readonly("has_atomic", &Card::has_atomic)
21 .def("get_prop", (Property* (Card::*)(uint32_t) const)&Card::get_prop) 35 .def("get_prop", (Property* (Card::*)(uint32_t) const)&Card::get_prop)
22 ; 36 ;
23 37
24 py::class_<DrmObject, DrmObject*>(m, "DrmObject") 38 py::class_<DrmObject, unique_ptr<DrmObject, py::nodelete>>(m, "DrmObject")
25 .def_property_readonly("id", &DrmObject::id) 39 .def_property_readonly("id", &DrmObject::id)
26 .def_property_readonly("idx", &DrmObject::idx) 40 .def_property_readonly("idx", &DrmObject::idx)
27 .def_property_readonly("card", &DrmObject::card) 41 .def_property_readonly("card", &DrmObject::card)
28 ; 42 ;
29 43
30 py::class_<DrmPropObject, DrmPropObject*>(m, "DrmPropObject", py::base<DrmObject>()) 44 py::class_<DrmPropObject, DrmObject, unique_ptr<DrmPropObject, py::nodelete>>(m, "DrmPropObject")
31 .def("refresh_props", &DrmPropObject::refresh_props) 45 .def("refresh_props", &DrmPropObject::refresh_props)
32 .def_property_readonly("prop_map", &DrmPropObject::get_prop_map) 46 .def_property_readonly("prop_map", &DrmPropObject::get_prop_map)
33 .def("get_prop_value", (uint64_t (DrmPropObject::*)(const string&) const)&DrmPropObject::get_prop_value) 47 .def("get_prop_value", (uint64_t (DrmPropObject::*)(const string&) const)&DrmPropObject::get_prop_value)
@@ -36,7 +50,7 @@ void init_pykmsbase(py::module &m)
36 .def("get_prop", &DrmPropObject::get_prop) 50 .def("get_prop", &DrmPropObject::get_prop)
37 ; 51 ;
38 52
39 py::class_<Connector, Connector*>(m, "Connector", py::base<DrmPropObject>()) 53 py::class_<Connector, DrmPropObject, unique_ptr<Connector, py::nodelete>>(m, "Connector")
40 .def_property_readonly("fullname", &Connector::fullname) 54 .def_property_readonly("fullname", &Connector::fullname)
41 .def("get_default_mode", &Connector::get_default_mode) 55 .def("get_default_mode", &Connector::get_default_mode)
42 .def("get_current_crtc", &Connector::get_current_crtc) 56 .def("get_current_crtc", &Connector::get_current_crtc)
@@ -49,7 +63,7 @@ void init_pykmsbase(py::module &m)
49 .def("refresh", &Connector::refresh) 63 .def("refresh", &Connector::refresh)
50 ; 64 ;
51 65
52 py::class_<Crtc, Crtc*>(m, "Crtc", py::base<DrmPropObject>()) 66 py::class_<Crtc, DrmPropObject, unique_ptr<Crtc, py::nodelete>>(m, "Crtc")
53 .def("set_mode", (int (Crtc::*)(Connector*, const Videomode&))&Crtc::set_mode) 67 .def("set_mode", (int (Crtc::*)(Connector*, const Videomode&))&Crtc::set_mode)
54 .def("set_mode", (int (Crtc::*)(Connector*, Framebuffer&, const Videomode&))&Crtc::set_mode) 68 .def("set_mode", (int (Crtc::*)(Connector*, Framebuffer&, const Videomode&))&Crtc::set_mode)
55 .def("disable_mode", &Crtc::disable_mode) 69 .def("disable_mode", &Crtc::disable_mode)
@@ -67,11 +81,11 @@ void init_pykmsbase(py::module &m)
67 .def("refresh", &Crtc::refresh) 81 .def("refresh", &Crtc::refresh)
68 ; 82 ;
69 83
70 py::class_<Encoder, Encoder*>(m, "Encoder", py::base<DrmPropObject>()) 84 py::class_<Encoder, DrmPropObject, unique_ptr<Encoder, py::nodelete>>(m, "Encoder")
71 .def("refresh", &Encoder::refresh) 85 .def("refresh", &Encoder::refresh)
72 ; 86 ;
73 87
74 py::class_<Plane, Plane*>(m, "Plane", py::base<DrmPropObject>()) 88 py::class_<Plane, DrmPropObject, unique_ptr<Plane, py::nodelete>>(m, "Plane")
75 .def("supports_crtc", &Plane::supports_crtc) 89 .def("supports_crtc", &Plane::supports_crtc)
76 .def_property_readonly("formats", &Plane::get_formats) 90 .def_property_readonly("formats", &Plane::get_formats)
77 .def_property_readonly("plane_type", &Plane::plane_type) 91 .def_property_readonly("plane_type", &Plane::plane_type)
@@ -84,12 +98,12 @@ void init_pykmsbase(py::module &m)
84 .value("Cursor", PlaneType::Cursor) 98 .value("Cursor", PlaneType::Cursor)
85 ; 99 ;
86 100
87 py::class_<Property, Property*>(m, "Property", py::base<DrmObject>()) 101 py::class_<Property, DrmObject, unique_ptr<Property, py::nodelete>>(m, "Property")
88 .def_property_readonly("name", &Property::name) 102 .def_property_readonly("name", &Property::name)
89 .def_property_readonly("enums", &Property::get_enums) 103 .def_property_readonly("enums", &Property::get_enums)
90 ; 104 ;
91 105
92 py::class_<Blob>(m, "Blob", py::base<DrmObject>()) 106 py::class_<Blob>(m, "Blob")
93 .def("__init__", [](Blob& instance, Card& card, py::buffer buf) { 107 .def("__init__", [](Blob& instance, Card& card, py::buffer buf) {
94 py::buffer_info info = buf.request(); 108 py::buffer_info info = buf.request();
95 if (info.ndim != 1) 109 if (info.ndim != 1)
@@ -98,17 +112,30 @@ void init_pykmsbase(py::module &m)
98 new (&instance) Blob(card, info.ptr, info.size * info.itemsize); 112 new (&instance) Blob(card, info.ptr, info.size * info.itemsize);
99 }) 113 })
100 .def_property_readonly("data", &Blob::data) 114 .def_property_readonly("data", &Blob::data)
101 ;
102 115
103 py::class_<Framebuffer>(m, "Framebuffer", py::base<DrmObject>()) 116 // XXX pybind11 doesn't support a base object (DrmObject) with custom holder-type,
117 // and a subclass with standard holder-type.
118 // So we just copy the DrmObject members here.
119 // Note that this means that python thinks we don't derive from DrmObject
120 .def_property_readonly("id", &DrmObject::id)
121 .def_property_readonly("idx", &DrmObject::idx)
122 .def_property_readonly("card", &DrmObject::card)
104 ; 123 ;
105 124
106 py::class_<Framebuffer>(m, "Framebuffer", py::base<Framebuffer>()) 125 py::class_<Framebuffer>(m, "Framebuffer")
107 .def_property_readonly("width", &Framebuffer::width) 126 .def_property_readonly("width", &Framebuffer::width)
108 .def_property_readonly("height", &Framebuffer::height) 127 .def_property_readonly("height", &Framebuffer::height)
128
129 // XXX pybind11 doesn't support a base object (DrmObject) with custom holder-type,
130 // and a subclass with standard holder-type.
131 // So we just copy the DrmObject members here.
132 // Note that this means that python thinks we don't derive from DrmObject
133 .def_property_readonly("id", &DrmObject::id)
134 .def_property_readonly("idx", &DrmObject::idx)
135 .def_property_readonly("card", &DrmObject::card)
109 ; 136 ;
110 137
111 py::class_<DumbFramebuffer>(m, "DumbFramebuffer", py::base<Framebuffer>()) 138 py::class_<DumbFramebuffer, Framebuffer>(m, "DumbFramebuffer")
112 .def(py::init<Card&, uint32_t, uint32_t, const string&>(), 139 .def(py::init<Card&, uint32_t, uint32_t, const string&>(),
113 py::keep_alive<1, 2>()) // Keep Card alive until this is destructed 140 py::keep_alive<1, 2>()) // Keep Card alive until this is destructed
114 .def(py::init<Card&, uint32_t, uint32_t, PixelFormat>(), 141 .def(py::init<Card&, uint32_t, uint32_t, PixelFormat>(),
@@ -120,7 +147,7 @@ void init_pykmsbase(py::module &m)
120 .def("offset", &DumbFramebuffer::offset) 147 .def("offset", &DumbFramebuffer::offset)
121 ; 148 ;
122 149
123 py::class_<ExtFramebuffer>(m, "ExtFramebuffer", py::base<Framebuffer>()) 150 py::class_<ExtFramebuffer, Framebuffer>(m, "ExtFramebuffer")
124 .def(py::init<Card&, uint32_t, uint32_t, PixelFormat, vector<int>, vector<uint32_t>, vector<uint32_t>>(), 151 .def(py::init<Card&, uint32_t, uint32_t, PixelFormat, vector<int>, vector<uint32_t>, vector<uint32_t>>(),
125 py::keep_alive<1, 2>()) // Keep Card alive until this is destructed 152 py::keep_alive<1, 2>()) // Keep Card alive until this is destructed
126 ; 153 ;
diff --git a/py/pykms/pykmsomap.cpp b/py/pykms/pykmsomap.cpp
index 2662a18..4fc7084 100644
--- a/py/pykms/pykmsomap.cpp
+++ b/py/pykms/pykmsomap.cpp
@@ -10,11 +10,11 @@ using namespace std;
10 10
11void init_pykmsomap(py::module &m) 11void init_pykmsomap(py::module &m)
12{ 12{
13 py::class_<OmapCard>(m, "OmapCard", py::base<Card>()) 13 py::class_<OmapCard, Card>(m, "OmapCard")
14 .def(py::init<>()) 14 .def(py::init<>())
15 ; 15 ;
16 16
17 py::class_<OmapFramebuffer> omapfb(m, "OmapFramebuffer", py::base<Framebuffer>()); 17 py::class_<OmapFramebuffer, Framebuffer> omapfb(m, "OmapFramebuffer");
18 18
19 // XXX we should use py::arithmetic() here to support or and and operators, but it's not supported in the pybind11 we use 19 // XXX we should use py::arithmetic() here to support or and and operators, but it's not supported in the pybind11 we use
20 py::enum_<OmapFramebuffer::Flags>(omapfb, "Flags") 20 py::enum_<OmapFramebuffer::Flags>(omapfb, "Flags")
diff --git a/py/pykms/pyvid.cpp b/py/pykms/pyvid.cpp
index 01177d5..6a6080e 100644
--- a/py/pykms/pyvid.cpp
+++ b/py/pykms/pyvid.cpp
@@ -11,7 +11,7 @@ using namespace std;
11 11
12void init_pyvid(py::module &m) 12void init_pyvid(py::module &m)
13{ 13{
14 py::class_<VideoDevice, VideoDevice*>(m, "VideoDevice") 14 py::class_<VideoDevice>(m, "VideoDevice")
15 .def(py::init<const string&>()) 15 .def(py::init<const string&>())
16 .def_property_readonly("fd", &VideoDevice::fd) 16 .def_property_readonly("fd", &VideoDevice::fd)
17 .def_property_readonly("has_capture", &VideoDevice::has_capture) 17 .def_property_readonly("has_capture", &VideoDevice::has_capture)
@@ -24,7 +24,7 @@ void init_pyvid(py::module &m)
24 .def("get_capture_devices", &VideoDevice::get_capture_devices) 24 .def("get_capture_devices", &VideoDevice::get_capture_devices)
25 ; 25 ;
26 26
27 py::class_<VideoStreamer, VideoStreamer*>(m, "VideoStreamer") 27 py::class_<VideoStreamer>(m, "VideoStreamer")
28 .def_property_readonly("fd", &VideoStreamer::fd) 28 .def_property_readonly("fd", &VideoStreamer::fd)
29 .def_property_readonly("ports", &VideoStreamer::get_ports) 29 .def_property_readonly("ports", &VideoStreamer::get_ports)
30 .def("set_port", &VideoStreamer::set_port) 30 .def("set_port", &VideoStreamer::set_port)