1 /*
2 * Copyright (C) 2018 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 #define LOG_TAG "hwc-resource-manager"
18
19 #include "resourcemanager.h"
20
21 #include <cutils/properties.h>
22 #include <log/log.h>
23 #include <sstream>
24 #include <string>
25
26 namespace android {
27
ResourceManager()28 ResourceManager::ResourceManager() : num_displays_(0), gralloc_(NULL) {
29 }
30
Init()31 int ResourceManager::Init() {
32 char path_pattern[PROPERTY_VALUE_MAX];
33 // Could be a valid path or it can have at the end of it the wildcard %
34 // which means that it will try open all devices until an error is met.
35 int path_len = property_get("hwc.drm.device", path_pattern, "/dev/dri/card0");
36 int ret = 0;
37 if (path_pattern[path_len - 1] != '%') {
38 ret = AddDrmDevice(std::string(path_pattern));
39 } else {
40 path_pattern[path_len - 1] = '\0';
41 for (int idx = 0; !ret; ++idx) {
42 std::ostringstream path;
43 path << path_pattern << idx;
44 ret = AddDrmDevice(path.str());
45 }
46 }
47
48 if (!num_displays_) {
49 ALOGE("Failed to initialize any displays");
50 return ret ? -EINVAL : ret;
51 }
52
53 return hw_get_module(GRALLOC_HARDWARE_MODULE_ID,
54 (const hw_module_t **)&gralloc_);
55 }
56
AddDrmDevice(std::string path)57 int ResourceManager::AddDrmDevice(std::string path) {
58 std::unique_ptr<DrmDevice> drm = std::make_unique<DrmDevice>();
59 int displays_added, ret;
60 std::tie(ret, displays_added) = drm->Init(path.c_str(), num_displays_);
61 if (ret)
62 return ret;
63 std::shared_ptr<Importer> importer;
64 importer.reset(Importer::CreateInstance(drm.get()));
65 if (!importer) {
66 ALOGE("Failed to create importer instance");
67 return -ENODEV;
68 }
69 importers_.push_back(importer);
70 drms_.push_back(std::move(drm));
71 num_displays_ += displays_added;
72 return ret;
73 }
74
AvailableWritebackConnector(int display)75 DrmConnector *ResourceManager::AvailableWritebackConnector(int display) {
76 DrmDevice *drm_device = GetDrmDevice(display);
77 DrmConnector *writeback_conn = NULL;
78 if (drm_device) {
79 writeback_conn = drm_device->AvailableWritebackConnector(display);
80 if (writeback_conn)
81 return writeback_conn;
82 }
83 for (auto &drm : drms_) {
84 if (drm.get() == drm_device)
85 continue;
86 writeback_conn = drm->AvailableWritebackConnector(display);
87 if (writeback_conn)
88 return writeback_conn;
89 }
90 return writeback_conn;
91 }
92
GetDrmDevice(int display)93 DrmDevice *ResourceManager::GetDrmDevice(int display) {
94 for (auto &drm : drms_) {
95 if (drm->HandlesDisplay(display))
96 return drm.get();
97 }
98 return NULL;
99 }
100
GetImporter(int display)101 std::shared_ptr<Importer> ResourceManager::GetImporter(int display) {
102 for (unsigned int i = 0; i < drms_.size(); i++) {
103 if (drms_[i]->HandlesDisplay(display))
104 return importers_[i];
105 }
106 return NULL;
107 }
108
gralloc()109 const gralloc_module_t *ResourceManager::gralloc() {
110 return gralloc_;
111 }
112 } // namespace android
113