Add support for DRM blobs
authorTomi Valkeinen <tomi.valkeinen@ti.com>
Wed, 25 May 2016 11:34:23 +0000 (14:34 +0300)
committerTomi Valkeinen <tomi.valkeinen@ti.com>
Wed, 25 May 2016 11:34:42 +0000 (14:34 +0300)
libkms++/blob.cpp [new file with mode: 0644]
libkms++/blob.h [new file with mode: 0644]
libkms++/decls.h
libkms++/drmpropobject.cpp
libkms++/drmpropobject.h
libkms++/kms++.h
py/pykmsbase.cpp

diff --git a/libkms++/blob.cpp b/libkms++/blob.cpp
new file mode 100644 (file)
index 0000000..10a71c6
--- /dev/null
@@ -0,0 +1,51 @@
+#include <xf86drm.h>
+#include <xf86drmMode.h>
+
+#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<uint8_t> 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<uint8_t>(data, data + blob->length);
+
+       drmModeFreePropertyBlob(blob);
+
+       return v;
+}
+
+}
diff --git a/libkms++/blob.h b/libkms++/blob.h
new file mode 100644 (file)
index 0000000..c6c230c
--- /dev/null
@@ -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<uint8_t> data();
+
+private:
+       bool m_created;
+};
+
+}
index 1bb968fbb51baeecac11faff70ec4dea953e3a33..e84b29a88972c760de749dd008da74f136490af2 100644 (file)
@@ -14,5 +14,6 @@ class DrmObject;
 class PageFlipHandlerBase;
 class Plane;
 class Property;
+class Blob;
 struct Videomode;
 }
index de9dfe337adbf76ee476726f980c596398faa12d..50f87a7cdf3b42421817f0fc71d1958dc9980e2d 100644 (file)
@@ -61,6 +61,13 @@ uint64_t DrmPropObject::get_prop_value(const string& name) const
        throw invalid_argument("property not found: " + name);
 }
 
+unique_ptr<Blob> DrmPropObject::get_prop_value_as_blob(const string& name) const
+{
+       uint32_t blob_id = (uint32_t)get_prop_value(name);
+
+       return unique_ptr<Blob>(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);
index 6dfd2a848a6e82163a891673934c0a5f4598be30..ec28d45ea08d52d44f7f0ba83d96c1da9479d498 100644 (file)
@@ -1,6 +1,7 @@
 #pragma once
 
 #include <map>
+#include <memory>
 
 #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<Blob> get_prop_value_as_blob(const std::string& name) const;
 
        const std::map<uint32_t, uint64_t>& get_prop_map() const { return m_prop_values; }
 
index 291cf13c6281aae4ed194f32e1005c8bbf021d51..3365ef7bb77430face1174614f9c075f4d6f4a75 100644 (file)
@@ -10,5 +10,6 @@
 #include "extframebuffer.h"
 #include "plane.h"
 #include "property.h"
+#include "blob.h"
 #include "pipeline.h"
 #include "pagefliphandler.h"
index aa86d9f3df36d0a5dbce6041238372d89fb7b6d8..83be9d2bcb351803e561219f684b18377830c401 100644 (file)
@@ -31,6 +31,9 @@ void init_pykmsbase(py::module &m)
        py::class_<DrmPropObject, DrmPropObject*>(m, "DrmPropObject", py::base<DrmObject>())
                        .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_<Connector, Connector*>(m, "Connector",  py::base<DrmPropObject>())
@@ -69,6 +72,17 @@ void init_pykmsbase(py::module &m)
                        .def_property_readonly("name", &Property::name)
                        ;
 
+       py::class_<Blob>(m, "Blob", py::base<DrmObject>())
+                       .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_<Framebuffer>(m, "Framebuffer",  py::base<DrmObject>())
                        ;