From 95de32aa7fbb1a2da547418b296f649ee4be1feb Mon Sep 17 00:00:00 2001 From: Tomi Valkeinen Date: Tue, 5 Sep 2017 11:01:17 +0300 Subject: 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(). --- py/pykms/__init__.py | 2 +- py/pykms/pykms.cpp | 5 ----- py/pykms/pykmsbase.cpp | 18 ++++++------------ py/tests/big_fb.py | 33 ++++++++++++--------------------- py/tests/db.py | 6 +++--- py/tests/modeset_event.py | 4 ++-- py/tests/sync.py | 4 ++-- 7 files changed, 26 insertions(+), 46 deletions(-) (limited to 'py') 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): seq = vbl_tuple[3] time = vbl_tuple[1] + vbl_tuple[2] / 1000000.0; - udata = pykms.__ob_unpack_helper(vbl_tuple[0]) + udata = vbl_tuple[0] yield DrmEvent(type, seq, time, udata) 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) { init_pykmsbase(m); - m.def("__ob_unpack_helper", [](uint64_t v) { - // AtomicReq::commit or Crtc::page_flip added a ref, so we can use borrowed = false - return py::object((PyObject*)v, false); - }); - init_pykmstest(m); 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) .def("set_mode", &Crtc::set_mode) .def("disable_mode", &Crtc::disable_mode) .def("page_flip", - [](Crtc* self, Framebuffer& fb, py::object ob) + [](Crtc* self, Framebuffer& fb, uint32_t data) { - // This adds a ref to the object, and must be unpacked with __ob_unpack_helper() - PyObject* pob = ob.ptr(); - Py_XINCREF(pob); - self->page_flip(fb, pob); - }) + self->page_flip(fb, (void*)(intptr_t)data); + }, py::arg("fb"), py::arg("data") = 0) .def("set_plane", &Crtc::set_plane) .def_property_readonly("possible_planes", &Crtc::get_possible_planes) .def_property_readonly("primary_plane", &Crtc::get_primary_plane) @@ -196,13 +193,10 @@ void init_pykmsbase(py::module &m) .def("add", (void (AtomicReq::*)(DrmPropObject*, const map&)) &AtomicReq::add) .def("test", &AtomicReq::test, py::arg("allow_modeset") = false) .def("commit", - [](AtomicReq* self, py::object ob, bool allow) + [](AtomicReq* self, uint32_t data, bool allow) { - // This adds a ref to the object, and must be unpacked with __ob_unpack_helper() - PyObject* pob = ob.ptr(); - Py_XINCREF(pob); - return self->commit(pob, allow); - }, py::arg("data"), py::arg("allow_modeset") = false) + return self->commit((void*)(intptr_t)data, allow); + }, py::arg("data") = 0, py::arg("allow_modeset") = false) .def("commit_sync", &AtomicReq::commit_sync, py::arg("allow_modeset") = false) ; } 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: self.flips = 0 self.frames = 0 self.time = 0 + self.flip_count = 100 def new_color(self): r = random.randrange(255) @@ -190,7 +191,7 @@ class bigFB_db: screen_offset += mode.hdisplay - req.commit(self) + req.commit(0) def handle_page_flip_separate(self): self.draw_buf ^= 1 @@ -222,9 +223,16 @@ class bigFB_db: screen_offset += mode.hdisplay - req.commit(self) + req.commit(0) def handle_page_flip_main(self, frame, time): + self.flip_count += 1 + + if self.flip_count < len(conn_list): + return + + self.flip_count = 0 + # statistics self.flips += 1 if self.time == 0: @@ -254,31 +262,14 @@ box_db.handle_page_flip_main(0, 0) def readdrm(fileobj, mask): for ev in card.read_events(): if ev.type == pykms.DrmEventType.FLIP_COMPLETE: - ev.data.handle_page_flip_main(ev.seq, ev.time) - -event_counter = len(conn_list) -def readdrm_counted(fileobj, mask): - global event_counter - - for ev in card.read_events(): - if ev.type == pykms.DrmEventType.FLIP_COMPLETE: - # we expect events for each display (crtc), but only execute the - # next drawing and flip when we have received the last event. - event_counter -= 1 - if event_counter == 0: - event_counter = len(conn_list) - ev.data.handle_page_flip_main(ev.seq, ev.time) + box_db.handle_page_flip_main(ev.seq, ev.time) def readkey(fileobj, mask): sys.stdin.readline() exit(0) sel = selectors.DefaultSelector() -if args.flipmode == 'single': - sel.register(card.fd, selectors.EVENT_READ, readdrm) -else: - sel.register(card.fd, selectors.EVENT_READ, readdrm_counted) - +sel.register(card.fd, selectors.EVENT_READ, readdrm) sel.register(sys.stdin, selectors.EVENT_READ, readkey) while 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(): if card.has_atomic: ctx = pykms.AtomicReq(card) ctx.add(crtc.primary_plane, "FB_ID", fb.id) - ctx.commit(self) + ctx.commit() else: - crtc.page_flip(fb, self) + crtc.page_flip(fb) if len(sys.argv) > 1: conn_name = sys.argv[1] @@ -77,7 +77,7 @@ def readdrm(fileobj, mask): #print("EVENT"); for ev in card.read_events(): if ev.type == pykms.DrmEventType.FLIP_COMPLETE: - ev.data.handle_page_flip(ev.seq, ev.time) + fliphandler.handle_page_flip(ev.seq, ev.time) def 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 def readdrm(fileobj, mask): for ev in card.read_events(): - ev.data(ev) + eventhandler(ev) def waitevent(sel): events = sel.select(1) @@ -67,7 +67,7 @@ if ret != 0: print("Atomic test failed: %d" % ret) sys.exit() -req.commit(eventhandler, allow_modeset = True) +req.commit(0, allow_modeset = True) waitevent(sel) input("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(): fence = self.timeline.create_fence(2 * self.flips - 1) req = pykms.AtomicReq(self.crtc.card) req.add(self.crtc.primary_plane, { 'FB_ID': fb.id, 'IN_FENCE_FD': fence.fd }) - req.commit(self) + req.commit() del fence # Arm a timer to signal the fence in 0.5s. @@ -207,7 +207,7 @@ def main(argv): def readdrm(fileobj, mask): for ev in card.read_events(): if ev.type == pykms.DrmEventType.FLIP_COMPLETE: - ev.data.handle_page_flip(ev.seq, ev.time) + flip_handler.handle_page_flip(ev.seq, ev.time) def readkey(fileobj, mask): sys.stdin.readline() -- cgit v1.2.3