From 2d14233bdb2302bffc1a241681f34933cb99c157 Mon Sep 17 00:00:00 2001 From: Tomi Valkeinen Date: Wed, 25 May 2016 14:34:23 +0300 Subject: Add support for DRM blobs --- libkms++/blob.cpp | 51 ++++++++++++++++++++++++++++++++++++++++++++++ libkms++/blob.h | 21 +++++++++++++++++++ libkms++/decls.h | 1 + libkms++/drmpropobject.cpp | 7 +++++++ libkms++/drmpropobject.h | 2 ++ libkms++/kms++.h | 1 + py/pykmsbase.cpp | 14 +++++++++++++ 7 files changed, 97 insertions(+) create mode 100644 libkms++/blob.cpp create mode 100644 libkms++/blob.h diff --git a/libkms++/blob.cpp b/libkms++/blob.cpp new file mode 100644 index 0000000..10a71c6 --- /dev/null +++ b/libkms++/blob.cpp @@ -0,0 +1,51 @@ +#include +#include + +#include "kms++.h" + +using namespace std; + +namespace kms +{ + +Blob::Blob(Card& card, uint32_t blob_id) + : DrmObject(card, blob_id, DRM_MODE_OBJECT_BLOB), m_created(false) +{ + // XXX should we verify that the blob_id is a blob object? +} + +Blob::Blob(Card& card, void* data, size_t len) + : DrmObject(card, DRM_MODE_OBJECT_BLOB), m_created(true) +{ + uint32_t id; + + int r = drmModeCreatePropertyBlob(card.fd(), data, len, &id); + if (r) + throw invalid_argument("FAILED TO CREATE PROP\n"); + + set_id(id); +} + +Blob::~Blob() +{ + if (m_created) + drmModeDestroyPropertyBlob(card().fd(), id()); +} + +vector Blob::data() +{ + drmModePropertyBlobPtr blob = drmModeGetPropertyBlob(card().fd(), id()); + + if (!blob) + throw invalid_argument("Blob data not available"); + + uint8_t* data = (uint8_t*)blob->data; + + auto v = vector(data, data + blob->length); + + drmModeFreePropertyBlob(blob); + + return v; +} + +} diff --git a/libkms++/blob.h b/libkms++/blob.h new file mode 100644 index 0000000..c6c230c --- /dev/null +++ b/libkms++/blob.h @@ -0,0 +1,21 @@ +#pragma once + +#include "drmobject.h" + +namespace kms +{ + +class Blob : public DrmObject +{ +public: + Blob(Card& card, uint32_t blob_id); + Blob(Card& card, void* data, size_t len); + virtual ~Blob(); + + std::vector data(); + +private: + bool m_created; +}; + +} diff --git a/libkms++/decls.h b/libkms++/decls.h index 1bb968f..e84b29a 100644 --- a/libkms++/decls.h +++ b/libkms++/decls.h @@ -14,5 +14,6 @@ class DrmObject; class PageFlipHandlerBase; class Plane; class Property; +class Blob; struct Videomode; } diff --git a/libkms++/drmpropobject.cpp b/libkms++/drmpropobject.cpp index de9dfe3..50f87a7 100644 --- a/libkms++/drmpropobject.cpp +++ b/libkms++/drmpropobject.cpp @@ -61,6 +61,13 @@ uint64_t DrmPropObject::get_prop_value(const string& name) const throw invalid_argument("property not found: " + name); } +unique_ptr DrmPropObject::get_prop_value_as_blob(const string& name) const +{ + uint32_t blob_id = (uint32_t)get_prop_value(name); + + return unique_ptr(new Blob(card(), blob_id)); +} + int DrmPropObject::set_prop_value(uint32_t id, uint64_t value) { return drmModeObjectSetProperty(card().fd(), this->id(), this->object_type(), id, value); diff --git a/libkms++/drmpropobject.h b/libkms++/drmpropobject.h index 6dfd2a8..ec28d45 100644 --- a/libkms++/drmpropobject.h +++ b/libkms++/drmpropobject.h @@ -1,6 +1,7 @@ #pragma once #include +#include #include "drmobject.h" #include "decls.h" @@ -15,6 +16,7 @@ public: void refresh_props(); uint64_t get_prop_value(uint32_t id) const; uint64_t get_prop_value(const std::string& name) const; + std::unique_ptr get_prop_value_as_blob(const std::string& name) const; const std::map& get_prop_map() const { return m_prop_values; } diff --git a/libkms++/kms++.h b/libkms++/kms++.h index 291cf13..3365ef7 100644 --- a/libkms++/kms++.h +++ b/libkms++/kms++.h @@ -10,5 +10,6 @@ #include "extframebuffer.h" #include "plane.h" #include "property.h" +#include "blob.h" #include "pipeline.h" #include "pagefliphandler.h" diff --git a/py/pykmsbase.cpp b/py/pykmsbase.cpp index aa86d9f..83be9d2 100644 --- a/py/pykmsbase.cpp +++ b/py/pykmsbase.cpp @@ -31,6 +31,9 @@ void init_pykmsbase(py::module &m) py::class_(m, "DrmPropObject", py::base()) .def("refresh_props", &DrmPropObject::refresh_props) .def_property_readonly("prop_map", &DrmPropObject::get_prop_map) + .def("get_prop_value", (uint64_t (DrmPropObject::*)(const string&) const)&DrmPropObject::get_prop_value) + .def("set_prop_value",(int (DrmPropObject::*)(const string&, uint64_t)) &DrmPropObject::set_prop_value) + .def("get_prop_value_as_blob", &DrmPropObject::get_prop_value_as_blob) ; py::class_(m, "Connector", py::base()) @@ -69,6 +72,17 @@ void init_pykmsbase(py::module &m) .def_property_readonly("name", &Property::name) ; + py::class_(m, "Blob", py::base()) + .def("__init__", [](Blob& instance, Card& card, py::buffer buf) { + py::buffer_info info = buf.request(); + if (info.ndim != 1) + throw std::runtime_error("Incompatible buffer dimension!"); + + new (&instance) Blob(card, info.ptr, info.size * info.itemsize); + }) + .def_property_readonly("data", &Blob::data) + ; + py::class_(m, "Framebuffer", py::base()) ; -- cgit v1.2.3