1 /*
2  * Copyright 2022 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 #pragma once
18 
19 #include <android-base/logging.h>
20 #include <android-base/unique_fd.h>
21 #include <xf86drm.h>
22 #include <xf86drmMode.h>
23 
24 #include <cstdint>
25 #include <limits>
26 #include <string>
27 #include <unordered_map>
28 
29 #include "Common.h"
30 
31 namespace aidl::android::hardware::graphics::composer3::impl {
32 
33 class DrmProperty {
34    public:
DrmProperty()35     DrmProperty() {}
DrmProperty(uint32_t id,uint64_t value,std::string name)36     DrmProperty(uint32_t id, uint64_t value, std::string name)
37         : mId(id), mValue(value), mName(name) {}
38 
~DrmProperty()39     ~DrmProperty() {}
40 
getId()41     uint32_t getId() const { return mId; }
42 
getValue()43     uint64_t getValue() const { return mValue; }
44 
getName()45     const std::string& getName() const { return mName; }
46 
47    private:
48     uint32_t mId = std::numeric_limits<uint32_t>::max();
49     uint64_t mValue = std::numeric_limits<uint64_t>::max();
50     std::string mName;
51 };
52 
53 template <typename T>
54 using DrmPropertyMember = DrmProperty T::*;
55 
56 template <typename T>
57 using DrmPropertyMemberMap = std::unordered_map<std::string, DrmPropertyMember<T>>;
58 
59 // Helper to many DrmProperty members for DrmCrtc, DrmConnector, and DrmPlane.
60 template <typename T>
LoadDrmProperties(::android::base::borrowed_fd drmFd,uint32_t objectId,uint32_t objectType,const DrmPropertyMemberMap<T> & objectPropertyMap,T * object)61 bool LoadDrmProperties(::android::base::borrowed_fd drmFd, uint32_t objectId, uint32_t objectType,
62                        const DrmPropertyMemberMap<T>& objectPropertyMap, T* object) {
63     auto drmProperties = drmModeObjectGetProperties(drmFd.get(), objectId, objectType);
64     if (!drmProperties) {
65         ALOGE("%s: Failed to get properties: %s", __FUNCTION__, strerror(errno));
66         return false;
67     }
68 
69     for (uint32_t i = 0; i < drmProperties->count_props; ++i) {
70         const auto propertyId = drmProperties->props[i];
71 
72         auto drmProperty = drmModeGetProperty(drmFd.get(), propertyId);
73         if (!drmProperty) {
74             ALOGE("%s: Failed to get property: %s", __FUNCTION__, strerror(errno));
75             continue;
76         }
77 
78         const auto propertyName = drmProperty->name;
79         const auto propertyValue = drmProperties->prop_values[i];
80 
81         auto it = objectPropertyMap.find(propertyName);
82         if (it != objectPropertyMap.end()) {
83             DEBUG_LOG("%s: Loaded property:%" PRIu32 " (%s) val:%" PRIu64, __FUNCTION__, propertyId,
84                       propertyName, propertyValue);
85 
86             auto& objectPointerToMember = it->second;
87             object->*objectPointerToMember = DrmProperty(propertyId, propertyValue, propertyName);
88         }
89 
90         drmModeFreeProperty(drmProperty);
91     }
92 
93     drmModeFreeObjectProperties(drmProperties);
94 
95     return true;
96 }
97 
98 }  // namespace aidl::android::hardware::graphics::composer3::impl
99