blob: c0f61619cc2f04666fe29a7da00d9435be51188f [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
Andrew Wolfersd47f2252025-02-26 20:38:23 +000021#include <cinttypes>
Roman Stratiienkoe78235c2021-12-23 17:36:12 +020022#include <cstdint>
Roman Stratiienko0f679aa2021-09-29 12:59:48 +030023#include <map>
Roman Stratiienkoabd8e532022-12-06 23:31:33 +020024#include <optional>
Sean Paulf72cccd2018-08-27 13:59:08 -040025#include <string>
Sean Paul6a55e9f2015-04-30 15:31:06 -040026#include <vector>
27
Andrew Wolferse778d032024-12-12 17:32:33 +000028#include "drm/DrmUnique.h"
29#include "utils/fd.h"
30#include "utils/log.h"
31
Sean Paul6a55e9f2015-04-30 15:31:06 -040032namespace android {
33
Sean Paul6a55e9f2015-04-30 15:31:06 -040034class DrmProperty {
35 public:
Zach Reiznerff30b522015-10-28 19:08:45 -070036 DrmProperty() = default;
Andrew Wolferse778d032024-12-12 17:32:33 +000037 DrmProperty(const SharedFd &fd, uint32_t obj_id, drmModePropertyPtr p,
38 uint64_t value);
Zach Reiznerff30b522015-10-28 19:08:45 -070039 DrmProperty(const DrmProperty &) = delete;
40 DrmProperty &operator=(const DrmProperty &) = delete;
Sean Paul6a55e9f2015-04-30 15:31:06 -040041
Andrew Wolferse778d032024-12-12 17:32:33 +000042 auto Init(const SharedFd &fd, uint32_t obj_id, drmModePropertyPtr p,
43 uint64_t value) -> void;
Roman Stratiienkoe2f2c922021-02-13 10:57:47 +020044 std::tuple<uint64_t, int> GetEnumValueWithName(const std::string &name) const;
Sean Paul6a55e9f2015-04-30 15:31:06 -040045
Roman Stratiienkoabd8e532022-12-06 23:31:33 +020046 auto GetId() const {
47 return id_;
48 }
Sean Paul6a55e9f2015-04-30 15:31:06 -040049
Roman Stratiienkoabd8e532022-12-06 23:31:33 +020050 auto GetName() const {
51 return name_;
52 }
Sean Paul6a55e9f2015-04-30 15:31:06 -040053
Roman Stratiienkoabd8e532022-12-06 23:31:33 +020054 auto GetValue() const -> std::optional<uint64_t>;
55
56 bool IsImmutable() const {
57 return id_ != 0 && (flags_ & DRM_MODE_PROP_IMMUTABLE) != 0;
58 }
59
60 bool IsRange() const {
61 return id_ != 0 && (flags_ & DRM_MODE_PROP_RANGE) != 0;
62 }
63
Drew Davenport5b583562025-01-29 09:04:22 -070064 bool IsBitmask() const {
65 return id_ != 0 && (flags_ & DRM_MODE_PROP_BITMASK) != 0;
66 }
67
Roman Stratiienkoabd8e532022-12-06 23:31:33 +020068 auto RangeMin() const -> std::tuple<int, uint64_t>;
69 auto RangeMax() const -> std::tuple<int, uint64_t>;
Alexandru Gheorghe2ed463c2019-01-08 19:21:08 +020070
Roman Stratiienko7fd8f882021-09-29 12:46:54 +030071 [[nodiscard]] auto AtomicSet(drmModeAtomicReq &pset, uint64_t value) const
72 -> bool;
73
Roman Stratiienko0f679aa2021-09-29 12:59:48 +030074 template <class E>
75 auto AddEnumToMap(const std::string &name, E key, std::map<E, uint64_t> &map)
76 -> bool;
77
Tim Van Pattena2f3efa2024-10-15 17:44:54 -060078 template <class E>
79 auto AddEnumToMapReverse(const std::string &name, E value,
80 std::map<uint64_t, E> &map) -> bool;
81
Roman Stratiienkoda2fcf62025-01-23 17:47:03 +020082 auto GetEnumMask(uint64_t &mask) -> bool;
83
Roman Stratiienkoe78235c2021-12-23 17:36:12 +020084 explicit operator bool() const {
Roman Stratiienko7fd8f882021-09-29 12:46:54 +030085 return id_ != 0;
86 }
87
Tim Van Pattena2f3efa2024-10-15 17:44:54 -060088 auto GetEnumNameFromValue(uint64_t value) const -> std::optional<std::string>;
89
Andrew Wolferse778d032024-12-12 17:32:33 +000090 bool IsBlob() const {
91 return id_ != 0 && (flags_ & DRM_MODE_PROP_BLOB) != 0;
92 }
93 template <typename T>
94 bool GetBlobData(std::vector<T> &data_out) const;
95
Sean Paul6a55e9f2015-04-30 15:31:06 -040096 private:
97 class DrmPropertyEnum {
98 public:
Roman Stratiienkoe78235c2021-12-23 17:36:12 +020099 explicit DrmPropertyEnum(drm_mode_property_enum *e);
Roman Stratiienkoe2f2c922021-02-13 10:57:47 +0200100 ~DrmPropertyEnum() = default;
Sean Paul6a55e9f2015-04-30 15:31:06 -0400101
Roman Stratiienkoabd8e532022-12-06 23:31:33 +0200102 uint64_t value;
103 std::string name;
Sean Paul6a55e9f2015-04-30 15:31:06 -0400104 };
105
Andrew Wolferse778d032024-12-12 17:32:33 +0000106 SharedFd fd_ = nullptr;
Roman Stratiienko7fd8f882021-09-29 12:46:54 +0300107 uint32_t obj_id_ = 0;
Zach Reiznerff30b522015-10-28 19:08:45 -0700108 uint32_t id_ = 0;
Sean Paul6a55e9f2015-04-30 15:31:06 -0400109
Zach Reiznerff30b522015-10-28 19:08:45 -0700110 uint32_t flags_ = 0;
Sean Paul6a55e9f2015-04-30 15:31:06 -0400111 std::string name_;
Zach Reiznerff30b522015-10-28 19:08:45 -0700112 uint64_t value_ = 0;
Sean Paul6a55e9f2015-04-30 15:31:06 -0400113
114 std::vector<uint64_t> values_;
115 std::vector<DrmPropertyEnum> enums_;
116 std::vector<uint32_t> blob_ids_;
117};
Roman Stratiienko0f679aa2021-09-29 12:59:48 +0300118
119template <class E>
120auto DrmProperty::AddEnumToMap(const std::string &name, E key,
121 std::map<E, uint64_t> &map) -> bool {
122 uint64_t enum_value = UINT64_MAX;
123 int err = 0;
124 std::tie(enum_value, err) = GetEnumValueWithName(name);
125 if (err == 0) {
126 map[key] = enum_value;
127 return true;
128 }
129
130 return false;
131}
132
Tim Van Pattena2f3efa2024-10-15 17:44:54 -0600133template <class E>
134auto DrmProperty::AddEnumToMapReverse(const std::string &name, E value,
135 std::map<uint64_t, E> &map) -> bool {
136 uint64_t enum_value = UINT64_MAX;
137 int err = 0;
138 std::tie(enum_value, err) = GetEnumValueWithName(name);
139 if (err == 0) {
140 map[enum_value] = value;
141 return true;
142 }
143
144 return false;
145}
146
Andrew Wolferse778d032024-12-12 17:32:33 +0000147template <typename T>
148bool DrmProperty::GetBlobData(std::vector<T> &data_out) const {
149 auto value = GetValue();
150 if (!fd_) {
151 ALOGE("Could not read blob data from property %s: No fd", name_.c_str());
152 return false;
153 }
154 if (!IsBlob()) {
155 ALOGE("Property %s is not blob type", name_.c_str());
156 return false;
157 }
158 if (!value.has_value()) {
159 ALOGE("Could not read blob data from property %s: No blob id",
160 name_.c_str());
161 return false;
162 }
163
164 auto blob = MakeDrmModePropertyBlobUnique(*fd_, value.value());
165 if (blob == nullptr) {
Andrew Wolfersd47f2252025-02-26 20:38:23 +0000166 ALOGE("Failed to read blob with id=%" PRIu64 " from property %s",
167 value.value(), name_.c_str());
Andrew Wolferse778d032024-12-12 17:32:33 +0000168 return false;
169 }
170
171 if (blob->length % sizeof(T) != 0) {
172 ALOGE(
Andrew Wolfersd47f2252025-02-26 20:38:23 +0000173 "Property %s blob size of %u bytes is not divisible by type argument "
Andrew Wolferse778d032024-12-12 17:32:33 +0000174 "size of %zu bytes",
175 name_.c_str(), blob->length, sizeof(T));
176 return false;
177 }
178
179 auto cast_data = static_cast<T *>(blob->data);
180 size_t cast_data_length = blob->length / sizeof(T);
181 data_out.assign(cast_data, cast_data + cast_data_length);
182
183 return true;
184}
185
Sean Paulf72cccd2018-08-27 13:59:08 -0400186} // namespace android