blob: 9664de0456036c01384dd6ffc5e542de504d3ad5 [file] [log] [blame]
Sean Paul6a55e9f2015-04-30 15:31:06 -04001/*
2 * Copyright (C) 2015 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
Roman Stratiienkobde95662022-12-10 20:27:58 +020017#pragma once
Sean Paul6a55e9f2015-04-30 15:31:06 -040018
Sean Paul6a55e9f2015-04-30 15:31:06 -040019#include <xf86drmMode.h>
Roman Stratiienkoaa3cd542020-08-29 11:26:16 +030020
Roman Stratiienkoe78235c2021-12-23 17:36:12 +020021#include <cstdint>
Roman Stratiienko0f679aa2021-09-29 12:59:48 +030022#include <map>
Roman Stratiienkoabd8e532022-12-06 23:31:33 +020023#include <optional>
Sean Paulf72cccd2018-08-27 13:59:08 -040024#include <string>
Sean Paul6a55e9f2015-04-30 15:31:06 -040025#include <vector>
26
Andrew Wolferse778d032024-12-12 17:32:33 +000027#include "drm/DrmUnique.h"
28#include "utils/fd.h"
29#include "utils/log.h"
30
Sean Paul6a55e9f2015-04-30 15:31:06 -040031namespace android {
32
Sean Paul6a55e9f2015-04-30 15:31:06 -040033class DrmProperty {
34 public:
Zach Reiznerff30b522015-10-28 19:08:45 -070035 DrmProperty() = default;
Andrew Wolferse778d032024-12-12 17:32:33 +000036 DrmProperty(const SharedFd &fd, uint32_t obj_id, drmModePropertyPtr p,
37 uint64_t value);
Zach Reiznerff30b522015-10-28 19:08:45 -070038 DrmProperty(const DrmProperty &) = delete;
39 DrmProperty &operator=(const DrmProperty &) = delete;
Sean Paul6a55e9f2015-04-30 15:31:06 -040040
Andrew Wolferse778d032024-12-12 17:32:33 +000041 auto Init(const SharedFd &fd, uint32_t obj_id, drmModePropertyPtr p,
42 uint64_t value) -> void;
Roman Stratiienkoe2f2c922021-02-13 10:57:47 +020043 std::tuple<uint64_t, int> GetEnumValueWithName(const std::string &name) const;
Sean Paul6a55e9f2015-04-30 15:31:06 -040044
Roman Stratiienkoabd8e532022-12-06 23:31:33 +020045 auto GetId() const {
46 return id_;
47 }
Sean Paul6a55e9f2015-04-30 15:31:06 -040048
Roman Stratiienkoabd8e532022-12-06 23:31:33 +020049 auto GetName() const {
50 return name_;
51 }
Sean Paul6a55e9f2015-04-30 15:31:06 -040052
Roman Stratiienkoabd8e532022-12-06 23:31:33 +020053 auto GetValue() const -> std::optional<uint64_t>;
54
55 bool IsImmutable() const {
56 return id_ != 0 && (flags_ & DRM_MODE_PROP_IMMUTABLE) != 0;
57 }
58
59 bool IsRange() const {
60 return id_ != 0 && (flags_ & DRM_MODE_PROP_RANGE) != 0;
61 }
62
Drew Davenport5b583562025-01-29 09:04:22 -070063 bool IsBitmask() const {
64 return id_ != 0 && (flags_ & DRM_MODE_PROP_BITMASK) != 0;
65 }
66
Roman Stratiienkoabd8e532022-12-06 23:31:33 +020067 auto RangeMin() const -> std::tuple<int, uint64_t>;
68 auto RangeMax() const -> std::tuple<int, uint64_t>;
Alexandru Gheorghe2ed463c2019-01-08 19:21:08 +020069
Roman Stratiienko7fd8f882021-09-29 12:46:54 +030070 [[nodiscard]] auto AtomicSet(drmModeAtomicReq &pset, uint64_t value) const
71 -> bool;
72
Roman Stratiienko0f679aa2021-09-29 12:59:48 +030073 template <class E>
74 auto AddEnumToMap(const std::string &name, E key, std::map<E, uint64_t> &map)
75 -> bool;
76
Tim Van Pattena2f3efa2024-10-15 17:44:54 -060077 template <class E>
78 auto AddEnumToMapReverse(const std::string &name, E value,
79 std::map<uint64_t, E> &map) -> bool;
80
Roman Stratiienkoda2fcf62025-01-23 17:47:03 +020081 auto GetEnumMask(uint64_t &mask) -> bool;
82
Roman Stratiienkoe78235c2021-12-23 17:36:12 +020083 explicit operator bool() const {
Roman Stratiienko7fd8f882021-09-29 12:46:54 +030084 return id_ != 0;
85 }
86
Tim Van Pattena2f3efa2024-10-15 17:44:54 -060087 auto GetEnumNameFromValue(uint64_t value) const -> std::optional<std::string>;
88
Andrew Wolferse778d032024-12-12 17:32:33 +000089 bool IsBlob() const {
90 return id_ != 0 && (flags_ & DRM_MODE_PROP_BLOB) != 0;
91 }
92 template <typename T>
93 bool GetBlobData(std::vector<T> &data_out) const;
94
Sean Paul6a55e9f2015-04-30 15:31:06 -040095 private:
96 class DrmPropertyEnum {
97 public:
Roman Stratiienkoe78235c2021-12-23 17:36:12 +020098 explicit DrmPropertyEnum(drm_mode_property_enum *e);
Roman Stratiienkoe2f2c922021-02-13 10:57:47 +020099 ~DrmPropertyEnum() = default;
Sean Paul6a55e9f2015-04-30 15:31:06 -0400100
Roman Stratiienkoabd8e532022-12-06 23:31:33 +0200101 uint64_t value;
102 std::string name;
Sean Paul6a55e9f2015-04-30 15:31:06 -0400103 };
104
Andrew Wolferse778d032024-12-12 17:32:33 +0000105 SharedFd fd_ = nullptr;
Roman Stratiienko7fd8f882021-09-29 12:46:54 +0300106 uint32_t obj_id_ = 0;
Zach Reiznerff30b522015-10-28 19:08:45 -0700107 uint32_t id_ = 0;
Sean Paul6a55e9f2015-04-30 15:31:06 -0400108
Zach Reiznerff30b522015-10-28 19:08:45 -0700109 uint32_t flags_ = 0;
Sean Paul6a55e9f2015-04-30 15:31:06 -0400110 std::string name_;
Zach Reiznerff30b522015-10-28 19:08:45 -0700111 uint64_t value_ = 0;
Sean Paul6a55e9f2015-04-30 15:31:06 -0400112
113 std::vector<uint64_t> values_;
114 std::vector<DrmPropertyEnum> enums_;
115 std::vector<uint32_t> blob_ids_;
116};
Roman Stratiienko0f679aa2021-09-29 12:59:48 +0300117
118template <class E>
119auto DrmProperty::AddEnumToMap(const std::string &name, E key,
120 std::map<E, uint64_t> &map) -> bool {
121 uint64_t enum_value = UINT64_MAX;
122 int err = 0;
123 std::tie(enum_value, err) = GetEnumValueWithName(name);
124 if (err == 0) {
125 map[key] = enum_value;
126 return true;
127 }
128
129 return false;
130}
131
Tim Van Pattena2f3efa2024-10-15 17:44:54 -0600132template <class E>
133auto DrmProperty::AddEnumToMapReverse(const std::string &name, E value,
134 std::map<uint64_t, E> &map) -> bool {
135 uint64_t enum_value = UINT64_MAX;
136 int err = 0;
137 std::tie(enum_value, err) = GetEnumValueWithName(name);
138 if (err == 0) {
139 map[enum_value] = value;
140 return true;
141 }
142
143 return false;
144}
145
Andrew Wolferse778d032024-12-12 17:32:33 +0000146template <typename T>
147bool DrmProperty::GetBlobData(std::vector<T> &data_out) const {
148 auto value = GetValue();
149 if (!fd_) {
150 ALOGE("Could not read blob data from property %s: No fd", name_.c_str());
151 return false;
152 }
153 if (!IsBlob()) {
154 ALOGE("Property %s is not blob type", name_.c_str());
155 return false;
156 }
157 if (!value.has_value()) {
158 ALOGE("Could not read blob data from property %s: No blob id",
159 name_.c_str());
160 return false;
161 }
162
163 auto blob = MakeDrmModePropertyBlobUnique(*fd_, value.value());
164 if (blob == nullptr) {
165 ALOGE("Failed to read blob with id=%d from property %s", value.value(),
166 name_.c_str());
167 return false;
168 }
169
170 if (blob->length % sizeof(T) != 0) {
171 ALOGE(
172 "Property %s blob size of %zu bytes is not divisible by type argument "
173 "size of %zu bytes",
174 name_.c_str(), blob->length, sizeof(T));
175 return false;
176 }
177
178 auto cast_data = static_cast<T *>(blob->data);
179 size_t cast_data_length = blob->length / sizeof(T);
180 data_out.assign(cast_data, cast_data + cast_data_length);
181
182 return true;
183}
184
Sean Paulf72cccd2018-08-27 13:59:08 -0400185} // namespace android