diff --git a/pyevdi/Buffer.cpp b/pyevdi/Buffer.cpp index 645ea68c..9876b175 100644 --- a/pyevdi/Buffer.cpp +++ b/pyevdi/Buffer.cpp @@ -1,9 +1,10 @@ // Copyright (c) 2022 DisplayLink (UK) Ltd. -#include "Buffer.h" -#include "../library/evdi_lib.h" #include #include +#include "../library/evdi_lib.h" +#include "Buffer.h" + int Buffer::numerator = 0; Buffer::Buffer(evdi_mode mode, evdi_handle evdiHandle) @@ -25,8 +26,13 @@ Buffer::Buffer(evdi_mode mode, evdi_handle evdiHandle) buffer.rect_count = 16; buffer.rects = reinterpret_cast( calloc(buffer.rect_count, sizeof(struct evdi_rect))); - buffer.buffer = - calloc(mode.width * mode.width, mode.bits_per_pixel / 8); + rects_span = std::span(buffer.rects, buffer.rect_count); + bytes_per_pixel = mode.bits_per_pixel / 8; + buffer_size = mode.width * mode.height * bytes_per_pixel; + buffer.buffer = calloc(1, buffer_size); + buffer_span = + std::span(reinterpret_cast(buffer.buffer), + buffer_size / sizeof(uint32_t)); evdi_register_buffer(evdiHandle, buffer); } diff --git a/pyevdi/Buffer.h b/pyevdi/Buffer.h index 58f2bb70..2d329f35 100644 --- a/pyevdi/Buffer.h +++ b/pyevdi/Buffer.h @@ -2,8 +2,12 @@ #ifndef BUFFER_H #define BUFFER_H -#include "../library/evdi_lib.h" +#include #include +#include +#include + +#include "../library/evdi_lib.h" class Buffer : public std::enable_shared_from_this { static int numerator; @@ -11,6 +15,10 @@ class Buffer : public std::enable_shared_from_this { public: evdi_buffer buffer; + size_t buffer_size; + std::span rects_span; + std::span buffer_span; + size_t bytes_per_pixel; Buffer(evdi_mode mode, evdi_handle evdiHandle); ~Buffer(); }; diff --git a/pyevdi/Card.cpp b/pyevdi/Card.cpp index f6532e08..0871df1a 100644 --- a/pyevdi/Card.cpp +++ b/pyevdi/Card.cpp @@ -1,8 +1,9 @@ // Copyright (c) 2022 DisplayLink (UK) Ltd. +#include + #include "../library/evdi_lib.h" -#include -#include "Card.h" #include "Buffer.h" +#include "Card.h" namespace py = pybind11; @@ -24,8 +25,8 @@ void card_C_mode_handler(struct evdi_mode mode, void *user_data) card->setMode(mode); card->makeBuffers(2); - if (card->m_modeHandler != nullptr) { - card->m_modeHandler(mode); + if (!card->mode_handler.is_none()) { + card->mode_handler(mode); } card->request_update(); @@ -53,23 +54,19 @@ void Card::clearBuffers() void dpms_handler(int dpms_mode, void * /*user_data*/) { py::module logging = py::module::import("logging"); - logging.attr("info")("Got dpms signal." + std::to_string(dpms_mode)); + logging.attr("info")(std::format("Got dpms signal: \"{}\"", dpms_mode)); } Card::Card(int device) : evdiHandle(evdi_open(device)) { if (evdiHandle == nullptr) { - throw py::value_error("Card /dev/dri/card" + - std::to_string(device) + - "does not exists!"); + throw py::value_error(std::format( + "Failed to open card \"/dev/dri/card{}\"", device)); } memset(&eventContext, 0, sizeof(eventContext)); - m_modeHandler = nullptr; - acquire_framebuffer_cb = nullptr; - eventContext.mode_changed_handler = &card_C_mode_handler; eventContext.update_ready_handler = &default_update_ready_handler; eventContext.dpms_handler = dpms_handler; @@ -161,8 +158,8 @@ void Card::grab_pixels() evdi_grab_pixels(evdiHandle, buffer_requested->buffer.rects, &buffer_requested->buffer.rect_count); - if (acquire_framebuffer_cb) - acquire_framebuffer_cb(std::move(buffer_requested)); + if (acquire_framebuffer_handler) + acquire_framebuffer_handler(std::move(buffer_requested)); buffer_requested = nullptr; request_update(); diff --git a/pyevdi/Card.h b/pyevdi/Card.h index 1e62fd56..8a908ea0 100644 --- a/pyevdi/Card.h +++ b/pyevdi/Card.h @@ -2,10 +2,16 @@ #ifndef CARD_H #define CARD_H -#include "Buffer.h" +#include +#include +#include #include #include +#include "Buffer.h" + +namespace py = pybind11; + class Card { evdi_handle evdiHandle; evdi_event_context eventContext; @@ -25,9 +31,11 @@ class Card { friend void card_C_mode_handler(struct evdi_mode mode, void *user_data); public: - std::function m_modeHandler; - std::function buffer)> - acquire_framebuffer_cb; + /// used py::function to allow lambdas to work + /// void(struct evdi_mode) + py::function mode_handler; + /// void(std::shared_ptr buffer) + py::function acquire_framebuffer_handler; explicit Card(int device); ~Card(); diff --git a/pyevdi/Makefile b/pyevdi/Makefile index e2f04b46..8a7c94e5 100644 --- a/pyevdi/Makefile +++ b/pyevdi/Makefile @@ -12,7 +12,7 @@ LIBABI := 1 INCL_DIRS := -I../library $$(python3 -m pybind11 --includes) # -fvisibility=hidden https://pybind11.readthedocs.io/en/stable/faq.html#someclass-declared-with-greater-visibility-than-the-type-of-its-field-someclass-member-wattributes -CXXFLAGS := $(INCL_DIRS) -std=c++11 -fPIC -fvisibility=hidden $(CXXFLAGS) +CXXFLAGS := $(INCL_DIRS) -std=c++20 -fPIC -fvisibility=hidden $(CXXFLAGS) LDFLAGS := -L../library -Wl,--no-undefined $$(python3-config --ldflags --embed) -shared diff --git a/pyevdi/PyEvdi.cpp b/pyevdi/PyEvdi.cpp index f30cc2a1..e10c56e7 100644 --- a/pyevdi/PyEvdi.cpp +++ b/pyevdi/PyEvdi.cpp @@ -1,12 +1,17 @@ // Copyright (c) 2022 DisplayLink (UK) Ltd. -#include "../library/evdi_lib.h" -#include -#include -#include "Card.h" -#include #include +#include +#include +#include #include #include +#include +#include +#include +#include + +#include "../library/evdi_lib.h" +#include "Card.h" namespace py = pybind11; @@ -33,7 +38,7 @@ void log_function(void * /*user_data*/, const char *format, ...) PYBIND11_MODULE(PyEvdi, m) { - m.doc() = "python bindings for evdi library"; + m.doc() = "Python bindings for evdi library"; evdi_logging el; el.function = &log_function; @@ -108,7 +113,7 @@ PYBIND11_MODULE(PyEvdi, m) .def("connect", &Card::connect) .def("disconnect", &Card::disconnect) .def("handle_events", &Card::handle_events) - .def_readwrite("acquire_framebuffer_cb", - &Card::acquire_framebuffer_cb) - .def_readwrite("mode_changed_handler", &Card::m_modeHandler); + .def_readwrite("acquire_framebuffer_handler", + &Card::acquire_framebuffer_handler) + .def_readwrite("mode_changed_handler", &Card::mode_handler); } diff --git a/pyevdi/README.md b/pyevdi/README.md index 511c7c6f..8f792893 100644 --- a/pyevdi/README.md +++ b/pyevdi/README.md @@ -18,8 +18,8 @@ make install # Install PyEvdi To run tests: ```bash -pip install pytest # Install test dependencies -pytest test # Run tests +pip install pytest pytest-mock # Install test dependencies +pytest test # Run tests ``` ### Generate `compile_commands.json` diff --git a/pyevdi/4K60HzTest.edid b/pyevdi/sample_edid/4K60HzTest.edid similarity index 100% rename from pyevdi/4K60HzTest.edid rename to pyevdi/sample_edid/4K60HzTest.edid diff --git a/pyevdi/sample_edid/README.md b/pyevdi/sample_edid/README.md new file mode 100644 index 00000000..c052c5e2 --- /dev/null +++ b/pyevdi/sample_edid/README.md @@ -0,0 +1,4 @@ +# How to get an EDID file +``` +cp /sys/class/drm/card0-eDP-1/edid edid.bin +``` \ No newline at end of file diff --git a/pyevdi/test/test_connect.py b/pyevdi/test/test_connect.py index c24f00b5..632e7d77 100644 --- a/pyevdi/test/test_connect.py +++ b/pyevdi/test/test_connect.py @@ -51,7 +51,7 @@ def testHandlingEventsTenTimesWithDefaultHandlers(): card.disconnect() card.close() -def my_acquire_framebuffer_cb(buffer) -> None: +def my_acquire_framebuffer_handler(buffer) -> None: print("received buffer", buffer.id) print("rect_count:", buffer.rect_count, "\nrects:") for i in buffer.rects: @@ -63,7 +63,7 @@ def my_acquire_framebuffer_cb(buffer) -> None: def testHandlingEventsTenTimesWithAquireFramebufferSet(): card = PyEvdi.Card(utilities.get_available_evdi_card()) - card.acquire_framebuffer_cb = my_acquire_framebuffer_cb + card.acquire_framebuffer_handler = my_acquire_framebuffer_handler edid = utilities.get_edid() card.connect(edid, len(edid), utilities._FullHDAreaLimit, utilities._FullHDAreaLimit * utilities._60Hz) diff --git a/pyevdi/test/utilities.py b/pyevdi/test/utilities.py index d22e2f00..2e432fc2 100644 --- a/pyevdi/test/utilities.py +++ b/pyevdi/test/utilities.py @@ -20,6 +20,6 @@ def get_available_evdi_card(): return -1 def get_edid(): - with open("4K60HzTest.edid", mode='rb') as file: + with open("sample_edid/4K60HzTest.edid", mode='rb') as file: ed = file.read() return ed