Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

PyEvdi Fixes #421

Merged
merged 2 commits into from
Jan 8, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 10 additions & 4 deletions pyevdi/Buffer.cpp
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
// Copyright (c) 2022 DisplayLink (UK) Ltd.
#include "Buffer.h"
#include "../library/evdi_lib.h"
#include <cstdlib>
#include <cstdio>

#include "../library/evdi_lib.h"
#include "Buffer.h"

int Buffer::numerator = 0;

Buffer::Buffer(evdi_mode mode, evdi_handle evdiHandle)
Expand All @@ -25,8 +26,13 @@ Buffer::Buffer(evdi_mode mode, evdi_handle evdiHandle)
buffer.rect_count = 16;
buffer.rects = reinterpret_cast<evdi_rect *>(
calloc(buffer.rect_count, sizeof(struct evdi_rect)));
buffer.buffer =
calloc(mode.width * mode.width, mode.bits_per_pixel / 8);
rects_span = std::span<evdi_rect>(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<uint32_t>(reinterpret_cast<uint32_t *>(buffer.buffer),
buffer_size / sizeof(uint32_t));

evdi_register_buffer(evdiHandle, buffer);
}
Expand Down
10 changes: 9 additions & 1 deletion pyevdi/Buffer.h
Original file line number Diff line number Diff line change
Expand Up @@ -2,15 +2,23 @@
#ifndef BUFFER_H
#define BUFFER_H

#include "../library/evdi_lib.h"
#include <cstddef>
#include <memory>
#include <cstddef>
#include <span>

#include "../library/evdi_lib.h"

class Buffer : public std::enable_shared_from_this<Buffer> {
static int numerator;
evdi_handle evdiHandle;

public:
evdi_buffer buffer;
size_t buffer_size;
std::span<evdi_rect> rects_span;
std::span<uint32_t> buffer_span;
size_t bytes_per_pixel;
Buffer(evdi_mode mode, evdi_handle evdiHandle);
~Buffer();
};
Expand Down
23 changes: 10 additions & 13 deletions pyevdi/Card.cpp
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
// Copyright (c) 2022 DisplayLink (UK) Ltd.
#include <format>

#include "../library/evdi_lib.h"
#include <pybind11/pybind11.h>
#include "Card.h"
#include "Buffer.h"
#include "Card.h"

namespace py = pybind11;

Expand All @@ -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();
Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -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();
Expand Down
16 changes: 12 additions & 4 deletions pyevdi/Card.h
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,16 @@
#ifndef CARD_H
#define CARD_H

#include "Buffer.h"
#include <pybind11/pybind11.h>
#include <pybind11/functional.h>
#include <functional>
#include <list>
#include <memory>

#include "Buffer.h"

namespace py = pybind11;

class Card {
evdi_handle evdiHandle;
evdi_event_context eventContext;
Expand All @@ -25,9 +31,11 @@ class Card {
friend void card_C_mode_handler(struct evdi_mode mode, void *user_data);

public:
std::function<void(struct evdi_mode)> m_modeHandler;
std::function<void(std::shared_ptr<Buffer> 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> buffer)
py::function acquire_framebuffer_handler;

explicit Card(int device);
~Card();
Expand Down
2 changes: 1 addition & 1 deletion pyevdi/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -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)
raldone01 marked this conversation as resolved.
Show resolved Hide resolved

LDFLAGS := -L../library -Wl,--no-undefined $$(python3-config --ldflags --embed) -shared

Expand Down
23 changes: 14 additions & 9 deletions pyevdi/PyEvdi.cpp
Original file line number Diff line number Diff line change
@@ -1,12 +1,17 @@
// Copyright (c) 2022 DisplayLink (UK) Ltd.
#include "../library/evdi_lib.h"
#include <pybind11/pybind11.h>
#include <pybind11/functional.h>
#include "Card.h"
#include <cstdio>
#include <cstdarg>
#include <cstdint>
#include <cstdio>
#include <pybind11/functional.h>
#include <pybind11/stl.h>
#include <pybind11/stl_bind.h>
#include <pybind11/numpy.h>
#include <pybind11/pybind11.h>
#include <pybind11/pytypes.h>
#include <span>

#include "../library/evdi_lib.h"
#include "Card.h"

namespace py = pybind11;

Expand All @@ -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;
Expand Down Expand Up @@ -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);
}
4 changes: 2 additions & 2 deletions pyevdi/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -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`
Expand Down
File renamed without changes.
4 changes: 4 additions & 0 deletions pyevdi/sample_edid/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
# How to get an EDID file
```
cp /sys/class/drm/card0-eDP-1/edid edid.bin
```
4 changes: 2 additions & 2 deletions pyevdi/test/test_connect.py
Original file line number Diff line number Diff line change
Expand Up @@ -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:
Expand All @@ -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)
Expand Down
2 changes: 1 addition & 1 deletion pyevdi/test/utilities.py
Original file line number Diff line number Diff line change
Expand Up @@ -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