aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTomi Valkeinen2017-09-05 03:01:17 -0500
committerTomi Valkeinen2017-09-05 03:15:28 -0500
commit95de32aa7fbb1a2da547418b296f649ee4be1feb (patch)
tree50f81d2afc63357e7cfc18e2b23b1cd67e977a72
parentd6300fcfb0bc420ff30a6c8f44f9b5fe862cdb3d (diff)
downloadexternal-kmsxx-95de32aa7fbb1a2da547418b296f649ee4be1feb.tar.gz
external-kmsxx-95de32aa7fbb1a2da547418b296f649ee4be1feb.tar.xz
external-kmsxx-95de32aa7fbb1a2da547418b296f649ee4be1feb.zip
py: drop the fancy event handling
Unfortunately the nice event handler added previously doesn't work: we may get multiple page-flip events, which would lead to unref'ing the passed python object multiple times, leading to memory corruption. I guess it's only possible to pass a plain int as user data to commit() and page_flip().
-rw-r--r--py/pykms/__init__.py2
-rw-r--r--py/pykms/pykms.cpp5
-rw-r--r--py/pykms/pykmsbase.cpp18
-rwxr-xr-xpy/tests/big_fb.py33
-rwxr-xr-xpy/tests/db.py6
-rwxr-xr-xpy/tests/modeset_event.py4
-rwxr-xr-xpy/tests/sync.py4
7 files changed, 26 insertions, 46 deletions
diff --git a/py/pykms/__init__.py b/py/pykms/__init__.py
index 3b5f743..746c917 100644
--- a/py/pykms/__init__.py
+++ b/py/pykms/__init__.py
@@ -130,7 +130,7 @@ def __card_read_events(self):
130 130
131 seq = vbl_tuple[3] 131 seq = vbl_tuple[3]
132 time = vbl_tuple[1] + vbl_tuple[2] / 1000000.0; 132 time = vbl_tuple[1] + vbl_tuple[2] / 1000000.0;
133 udata = pykms.__ob_unpack_helper(vbl_tuple[0]) 133 udata = vbl_tuple[0]
134 134
135 yield DrmEvent(type, seq, time, udata) 135 yield DrmEvent(type, seq, time, udata)
136 136
diff --git a/py/pykms/pykms.cpp b/py/pykms/pykms.cpp
index 7752f19..1e54c9b 100644
--- a/py/pykms/pykms.cpp
+++ b/py/pykms/pykms.cpp
@@ -20,11 +20,6 @@ PYBIND11_PLUGIN(pykms) {
20 20
21 init_pykmsbase(m); 21 init_pykmsbase(m);
22 22
23 m.def("__ob_unpack_helper", [](uint64_t v) {
24 // AtomicReq::commit or Crtc::page_flip added a ref, so we can use borrowed = false
25 return py::object((PyObject*)v, false);
26 });
27
28 init_pykmstest(m); 23 init_pykmstest(m);
29 24
30 init_pyvid(m); 25 init_pyvid(m);
diff --git a/py/pykms/pykmsbase.cpp b/py/pykms/pykmsbase.cpp
index 604e07c..e53fe54 100644
--- a/py/pykms/pykmsbase.cpp
+++ b/py/pykms/pykmsbase.cpp
@@ -53,13 +53,10 @@ void init_pykmsbase(py::module &m)
53 .def("set_mode", &Crtc::set_mode) 53 .def("set_mode", &Crtc::set_mode)
54 .def("disable_mode", &Crtc::disable_mode) 54 .def("disable_mode", &Crtc::disable_mode)
55 .def("page_flip", 55 .def("page_flip",
56 [](Crtc* self, Framebuffer& fb, py::object ob) 56 [](Crtc* self, Framebuffer& fb, uint32_t data)
57 { 57 {
58 // This adds a ref to the object, and must be unpacked with __ob_unpack_helper() 58 self->page_flip(fb, (void*)(intptr_t)data);
59 PyObject* pob = ob.ptr(); 59 }, py::arg("fb"), py::arg("data") = 0)
60 Py_XINCREF(pob);
61 self->page_flip(fb, pob);
62 })
63 .def("set_plane", &Crtc::set_plane) 60 .def("set_plane", &Crtc::set_plane)
64 .def_property_readonly("possible_planes", &Crtc::get_possible_planes) 61 .def_property_readonly("possible_planes", &Crtc::get_possible_planes)
65 .def_property_readonly("primary_plane", &Crtc::get_primary_plane) 62 .def_property_readonly("primary_plane", &Crtc::get_primary_plane)
@@ -196,13 +193,10 @@ void init_pykmsbase(py::module &m)
196 .def("add", (void (AtomicReq::*)(DrmPropObject*, const map<string, uint64_t>&)) &AtomicReq::add) 193 .def("add", (void (AtomicReq::*)(DrmPropObject*, const map<string, uint64_t>&)) &AtomicReq::add)
197 .def("test", &AtomicReq::test, py::arg("allow_modeset") = false) 194 .def("test", &AtomicReq::test, py::arg("allow_modeset") = false)
198 .def("commit", 195 .def("commit",
199 [](AtomicReq* self, py::object ob, bool allow) 196 [](AtomicReq* self, uint32_t data, bool allow)
200 { 197 {
201 // This adds a ref to the object, and must be unpacked with __ob_unpack_helper() 198 return self->commit((void*)(intptr_t)data, allow);
202 PyObject* pob = ob.ptr(); 199 }, py::arg("data") = 0, py::arg("allow_modeset") = false)
203 Py_XINCREF(pob);
204 return self->commit(pob, allow);
205 }, py::arg("data"), py::arg("allow_modeset") = false)
206 .def("commit_sync", &AtomicReq::commit_sync, py::arg("allow_modeset") = false) 200 .def("commit_sync", &AtomicReq::commit_sync, py::arg("allow_modeset") = false)
207 ; 201 ;
208} 202}
diff --git a/py/tests/big_fb.py b/py/tests/big_fb.py
index 1642376..54de685 100755
--- a/py/tests/big_fb.py
+++ b/py/tests/big_fb.py
@@ -112,6 +112,7 @@ class bigFB_db:
112 self.flips = 0 112 self.flips = 0
113 self.frames = 0 113 self.frames = 0
114 self.time = 0 114 self.time = 0
115 self.flip_count = 100
115 116
116 def new_color(self): 117 def new_color(self):
117 r = random.randrange(255) 118 r = random.randrange(255)
@@ -190,7 +191,7 @@ class bigFB_db:
190 191
191 screen_offset += mode.hdisplay 192 screen_offset += mode.hdisplay
192 193
193 req.commit(self) 194 req.commit(0)
194 195
195 def handle_page_flip_separate(self): 196 def handle_page_flip_separate(self):
196 self.draw_buf ^= 1 197 self.draw_buf ^= 1
@@ -222,9 +223,16 @@ class bigFB_db:
222 223
223 screen_offset += mode.hdisplay 224 screen_offset += mode.hdisplay
224 225
225 req.commit(self) 226 req.commit(0)
226 227
227 def handle_page_flip_main(self, frame, time): 228 def handle_page_flip_main(self, frame, time):
229 self.flip_count += 1
230
231 if self.flip_count < len(conn_list):
232 return
233
234 self.flip_count = 0
235
228 # statistics 236 # statistics
229 self.flips += 1 237 self.flips += 1
230 if self.time == 0: 238 if self.time == 0:
@@ -254,31 +262,14 @@ box_db.handle_page_flip_main(0, 0)
254def readdrm(fileobj, mask): 262def readdrm(fileobj, mask):
255 for ev in card.read_events(): 263 for ev in card.read_events():
256 if ev.type == pykms.DrmEventType.FLIP_COMPLETE: 264 if ev.type == pykms.DrmEventType.FLIP_COMPLETE:
257 ev.data.handle_page_flip_main(ev.seq, ev.time) 265 box_db.handle_page_flip_main(ev.seq, ev.time)
258
259event_counter = len(conn_list)
260def readdrm_counted(fileobj, mask):
261 global event_counter
262
263 for ev in card.read_events():
264 if ev.type == pykms.DrmEventType.FLIP_COMPLETE:
265 # we expect events for each display (crtc), but only execute the
266 # next drawing and flip when we have received the last event.
267 event_counter -= 1
268 if event_counter == 0:
269 event_counter = len(conn_list)
270 ev.data.handle_page_flip_main(ev.seq, ev.time)
271 266
272def readkey(fileobj, mask): 267def readkey(fileobj, mask):
273 sys.stdin.readline() 268 sys.stdin.readline()
274 exit(0) 269 exit(0)
275 270
276sel = selectors.DefaultSelector() 271sel = selectors.DefaultSelector()
277if args.flipmode == 'single': 272sel.register(card.fd, selectors.EVENT_READ, readdrm)
278 sel.register(card.fd, selectors.EVENT_READ, readdrm)
279else:
280 sel.register(card.fd, selectors.EVENT_READ, readdrm_counted)
281
282sel.register(sys.stdin, selectors.EVENT_READ, readkey) 273sel.register(sys.stdin, selectors.EVENT_READ, readkey)
283 274
284while True: 275while True:
diff --git a/py/tests/db.py b/py/tests/db.py
index 660364d..f7b13eb 100755
--- a/py/tests/db.py
+++ b/py/tests/db.py
@@ -52,9 +52,9 @@ class FlipHandler():
52 if card.has_atomic: 52 if card.has_atomic:
53 ctx = pykms.AtomicReq(card) 53 ctx = pykms.AtomicReq(card)
54 ctx.add(crtc.primary_plane, "FB_ID", fb.id) 54 ctx.add(crtc.primary_plane, "FB_ID", fb.id)
55 ctx.commit(self) 55 ctx.commit()
56 else: 56 else:
57 crtc.page_flip(fb, self) 57 crtc.page_flip(fb)
58 58
59if len(sys.argv) > 1: 59if len(sys.argv) > 1:
60 conn_name = sys.argv[1] 60 conn_name = sys.argv[1]
@@ -77,7 +77,7 @@ def readdrm(fileobj, mask):
77 #print("EVENT"); 77 #print("EVENT");
78 for ev in card.read_events(): 78 for ev in card.read_events():
79 if ev.type == pykms.DrmEventType.FLIP_COMPLETE: 79 if ev.type == pykms.DrmEventType.FLIP_COMPLETE:
80 ev.data.handle_page_flip(ev.seq, ev.time) 80 fliphandler.handle_page_flip(ev.seq, ev.time)
81 81
82 82
83def readkey(fileobj, mask): 83def readkey(fileobj, mask):
diff --git a/py/tests/modeset_event.py b/py/tests/modeset_event.py
index 0957e51..11cfd58 100755
--- a/py/tests/modeset_event.py
+++ b/py/tests/modeset_event.py
@@ -6,7 +6,7 @@ import sys
6 6
7def readdrm(fileobj, mask): 7def readdrm(fileobj, mask):
8 for ev in card.read_events(): 8 for ev in card.read_events():
9 ev.data(ev) 9 eventhandler(ev)
10 10
11def waitevent(sel): 11def waitevent(sel):
12 events = sel.select(1) 12 events = sel.select(1)
@@ -67,7 +67,7 @@ if ret != 0:
67 print("Atomic test failed: %d" % ret) 67 print("Atomic test failed: %d" % ret)
68 sys.exit() 68 sys.exit()
69 69
70req.commit(eventhandler, allow_modeset = True) 70req.commit(0, allow_modeset = True)
71waitevent(sel) 71waitevent(sel)
72 72
73input("press enter to exit\n") 73input("press enter to exit\n")
diff --git a/py/tests/sync.py b/py/tests/sync.py
index 4616ee8..e394c8d 100755
--- a/py/tests/sync.py
+++ b/py/tests/sync.py
@@ -148,7 +148,7 @@ class FlipHandler():
148 fence = self.timeline.create_fence(2 * self.flips - 1) 148 fence = self.timeline.create_fence(2 * self.flips - 1)
149 req = pykms.AtomicReq(self.crtc.card) 149 req = pykms.AtomicReq(self.crtc.card)
150 req.add(self.crtc.primary_plane, { 'FB_ID': fb.id, 'IN_FENCE_FD': fence.fd }) 150 req.add(self.crtc.primary_plane, { 'FB_ID': fb.id, 'IN_FENCE_FD': fence.fd })
151 req.commit(self) 151 req.commit()
152 del fence 152 del fence
153 153
154 # Arm a timer to signal the fence in 0.5s. 154 # Arm a timer to signal the fence in 0.5s.
@@ -207,7 +207,7 @@ def main(argv):
207 def readdrm(fileobj, mask): 207 def readdrm(fileobj, mask):
208 for ev in card.read_events(): 208 for ev in card.read_events():
209 if ev.type == pykms.DrmEventType.FLIP_COMPLETE: 209 if ev.type == pykms.DrmEventType.FLIP_COMPLETE:
210 ev.data.handle_page_flip(ev.seq, ev.time) 210 flip_handler.handle_page_flip(ev.seq, ev.time)
211 211
212 def readkey(fileobj, mask): 212 def readkey(fileobj, mask):
213 sys.stdin.readline() 213 sys.stdin.readline()