drm_hwcomposer: Add blob support to DrmProperty
This changes adds support for accessing blob data of DrmProperties with
type casting. When invoked, the data corresponding to the blob id
indicated by the property value is read from the device, and returned
as a vector with the provided template typing.
This change adds the fd as an additional init parameter for DrmProperty,
which is required in order to read the blob data.
Change-Id: I9531d0e7e2f13a4fd2840564783859d1dec1efd5
Signed-off-by: Andrew Wolfers <aswolfers@google.com>
diff --git a/drm/DrmDevice.cpp b/drm/DrmDevice.cpp
index 6fd5c0c..fa5849f 100644
--- a/drm/DrmDevice.cpp
+++ b/drm/DrmDevice.cpp
@@ -200,7 +200,7 @@
drmModePropertyPtr p = drmModeGetProperty(*GetFd(), props->props[i]);
if (strcmp(p->name, prop_name) == 0) {
// NOLINTNEXTLINE(cppcoreguidelines-pro-bounds-pointer-arithmetic)
- property->Init(obj_id, p, props->prop_values[i]);
+ property->Init(GetFd(), obj_id, p, props->prop_values[i]);
found = true;
}
drmModeFreeProperty(p);
diff --git a/drm/DrmProperty.cpp b/drm/DrmProperty.cpp
index 8dc62f6..24a67bc 100644
--- a/drm/DrmProperty.cpp
+++ b/drm/DrmProperty.cpp
@@ -35,12 +35,14 @@
: value(e->value), name(e->name) {
}
-DrmProperty::DrmProperty(uint32_t obj_id, drmModePropertyPtr p,
- uint64_t value) {
- Init(obj_id, p, value);
+DrmProperty::DrmProperty(const SharedFd &fd, uint32_t obj_id,
+ drmModePropertyPtr p, uint64_t value) {
+ Init(fd, obj_id, p, value);
}
-void DrmProperty::Init(uint32_t obj_id, drmModePropertyPtr p, uint64_t value) {
+void DrmProperty::Init(const SharedFd &fd, uint32_t obj_id,
+ drmModePropertyPtr p, uint64_t value) {
+ fd_ = fd;
obj_id_ = obj_id;
id_ = p->prop_id;
flags_ = p->flags;
diff --git a/drm/DrmProperty.h b/drm/DrmProperty.h
index 99bddb1..9664de0 100644
--- a/drm/DrmProperty.h
+++ b/drm/DrmProperty.h
@@ -24,16 +24,22 @@
#include <string>
#include <vector>
+#include "drm/DrmUnique.h"
+#include "utils/fd.h"
+#include "utils/log.h"
+
namespace android {
class DrmProperty {
public:
DrmProperty() = default;
- DrmProperty(uint32_t obj_id, drmModePropertyPtr p, uint64_t value);
+ DrmProperty(const SharedFd &fd, uint32_t obj_id, drmModePropertyPtr p,
+ uint64_t value);
DrmProperty(const DrmProperty &) = delete;
DrmProperty &operator=(const DrmProperty &) = delete;
- auto Init(uint32_t obj_id, drmModePropertyPtr p, uint64_t value) -> void;
+ auto Init(const SharedFd &fd, uint32_t obj_id, drmModePropertyPtr p,
+ uint64_t value) -> void;
std::tuple<uint64_t, int> GetEnumValueWithName(const std::string &name) const;
auto GetId() const {
@@ -80,6 +86,12 @@
auto GetEnumNameFromValue(uint64_t value) const -> std::optional<std::string>;
+ bool IsBlob() const {
+ return id_ != 0 && (flags_ & DRM_MODE_PROP_BLOB) != 0;
+ }
+ template <typename T>
+ bool GetBlobData(std::vector<T> &data_out) const;
+
private:
class DrmPropertyEnum {
public:
@@ -90,6 +102,7 @@
std::string name;
};
+ SharedFd fd_ = nullptr;
uint32_t obj_id_ = 0;
uint32_t id_ = 0;
@@ -130,4 +143,43 @@
return false;
}
+template <typename T>
+bool DrmProperty::GetBlobData(std::vector<T> &data_out) const {
+ auto value = GetValue();
+ if (!fd_) {
+ ALOGE("Could not read blob data from property %s: No fd", name_.c_str());
+ return false;
+ }
+ if (!IsBlob()) {
+ ALOGE("Property %s is not blob type", name_.c_str());
+ return false;
+ }
+ if (!value.has_value()) {
+ ALOGE("Could not read blob data from property %s: No blob id",
+ name_.c_str());
+ return false;
+ }
+
+ auto blob = MakeDrmModePropertyBlobUnique(*fd_, value.value());
+ if (blob == nullptr) {
+ ALOGE("Failed to read blob with id=%d from property %s", value.value(),
+ name_.c_str());
+ return false;
+ }
+
+ if (blob->length % sizeof(T) != 0) {
+ ALOGE(
+ "Property %s blob size of %zu bytes is not divisible by type argument "
+ "size of %zu bytes",
+ name_.c_str(), blob->length, sizeof(T));
+ return false;
+ }
+
+ auto cast_data = static_cast<T *>(blob->data);
+ size_t cast_data_length = blob->length / sizeof(T);
+ data_out.assign(cast_data, cast_data + cast_data_length);
+
+ return true;
+}
+
} // namespace android