xref: /aosp_15_r20/external/drm_hwcomposer/drm/DrmProperty.cpp (revision 0a9764fe0a15e71ebbeb85e87e10990c23aab47f)
1 /*
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 
17 // NOLINTNEXTLINE(cppcoreguidelines-macro-usage)
18 #define LOG_TAG "drmhwc"
19 
20 #include "DrmProperty.h"
21 
22 #include <xf86drmMode.h>
23 
24 #include <cerrno>
25 #include <cinttypes>
26 #include <cstdint>
27 #include <string>
28 
29 #include "DrmDevice.h"
30 #include "utils/log.h"
31 
32 namespace android {
33 
DrmPropertyEnum(drm_mode_property_enum * e)34 DrmProperty::DrmPropertyEnum::DrmPropertyEnum(drm_mode_property_enum *e)
35     : value(e->value), name(e->name) {
36 }
37 
DrmProperty(uint32_t obj_id,drmModePropertyPtr p,uint64_t value)38 DrmProperty::DrmProperty(uint32_t obj_id, drmModePropertyPtr p,
39                          uint64_t value) {
40   Init(obj_id, p, value);
41 }
42 
Init(uint32_t obj_id,drmModePropertyPtr p,uint64_t value)43 void DrmProperty::Init(uint32_t obj_id, drmModePropertyPtr p, uint64_t value) {
44   obj_id_ = obj_id;
45   id_ = p->prop_id;
46   flags_ = p->flags;
47   name_ = p->name;
48   value_ = value;
49 
50   for (int i = 0; i < p->count_values; ++i)
51     // NOLINTNEXTLINE(cppcoreguidelines-pro-bounds-pointer-arithmetic):
52     values_.emplace_back(p->values[i]);
53 
54   for (int i = 0; i < p->count_enums; ++i)
55     // NOLINTNEXTLINE(cppcoreguidelines-pro-bounds-pointer-arithmetic):
56     enums_.emplace_back(&p->enums[i]);
57 
58   for (int i = 0; i < p->count_blobs; ++i)
59     // NOLINTNEXTLINE(cppcoreguidelines-pro-bounds-pointer-arithmetic):
60     blob_ids_.emplace_back(p->blob_ids[i]);
61 }
62 
GetValue() const63 std::optional<uint64_t> DrmProperty::GetValue() const {
64   if ((flags_ & DRM_MODE_PROP_BLOB) != 0)
65     return value_;
66 
67   if (values_.empty())
68     return {};
69 
70   if ((flags_ & DRM_MODE_PROP_RANGE) != 0)
71     return value_;
72 
73   if ((flags_ & DRM_MODE_PROP_ENUM) != 0) {
74     if (value_ >= enums_.size())
75       return {};
76 
77     return enums_[value_].value;
78   }
79 
80   if ((flags_ & DRM_MODE_PROP_OBJECT) != 0)
81     return value_;
82 
83   return {};
84 }
85 
RangeMin() const86 std::tuple<int, uint64_t> DrmProperty::RangeMin() const {
87   if (!IsRange())
88     return std::make_tuple(-EINVAL, 0);
89   if (values_.empty())
90     return std::make_tuple(-ENOENT, 0);
91 
92   return std::make_tuple(0, values_[0]);
93 }
94 
RangeMax() const95 std::tuple<int, uint64_t> DrmProperty::RangeMax() const {
96   if (!IsRange())
97     return std::make_tuple(-EINVAL, 0);
98   if (values_.size() < 2)
99     return std::make_tuple(-ENOENT, 0);
100 
101   return std::make_tuple(0, values_[1]);
102 }
103 
GetEnumValueWithName(const std::string & name) const104 std::tuple<uint64_t, int> DrmProperty::GetEnumValueWithName(
105     const std::string &name) const {
106   for (const auto &it : enums_) {
107     if (it.name == name) {
108       return std::make_tuple(it.value, 0);
109     }
110   }
111 
112   return std::make_tuple(UINT64_MAX, -EINVAL);
113 }
114 
AtomicSet(drmModeAtomicReq & pset,uint64_t value) const115 auto DrmProperty::AtomicSet(drmModeAtomicReq &pset, uint64_t value) const
116     -> bool {
117   if (id_ == 0) {
118     ALOGE("AtomicSet() is called on non-initialized property!");
119     return false;
120   }
121   if (drmModeAtomicAddProperty(&pset, obj_id_, id_, value) < 0) {
122     ALOGE("Failed to add obj_id: %u, prop_id: %u (%s) to pset", obj_id_, id_,
123           name_.c_str());
124     return false;
125   }
126   return true;
127 }
128 
GetEnumNameFromValue(uint64_t value) const129 std::optional<std::string> DrmProperty::GetEnumNameFromValue(
130     uint64_t value) const {
131   if (enums_.empty()) {
132     ALOGE("No enum values for property: %s", name_.c_str());
133     return {};
134   }
135 
136   for (const auto &it : enums_) {
137     if (it.value == value) {
138       return it.name;
139     }
140   }
141 
142   ALOGE("Property '%s' has no matching enum for value: %" PRIu64, name_.c_str(),
143         value);
144   return {};
145 }
146 
147 }  // namespace android
148