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) {
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("ro.vendor.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   return ret;
53 }
54 
AddDrmDevice(std::string path)55 int ResourceManager::AddDrmDevice(std::string path) {
56   std::unique_ptr<DrmDevice> drm = std::make_unique<DrmDevice>();
57   int displays_added, ret;
58   std::tie(ret, displays_added) = drm->Init(path.c_str(), num_displays_);
59   if (ret)
60     return ret;
61   drms_.push_back(std::move(drm));
62   num_displays_ += displays_added;
63   return ret;
64 }
65 
AvailableWritebackConnector(int display)66 DrmConnector *ResourceManager::AvailableWritebackConnector(int display) {
67   DrmDevice *drm_device = GetDrmDevice(display);
68   DrmConnector *writeback_conn = NULL;
69   if (drm_device) {
70     writeback_conn = drm_device->AvailableWritebackConnector(display);
71     if (writeback_conn)
72       return writeback_conn;
73   }
74   for (auto &drm : drms_) {
75     if (drm.get() == drm_device)
76       continue;
77     writeback_conn = drm->AvailableWritebackConnector(display);
78     if (writeback_conn)
79       return writeback_conn;
80   }
81   return writeback_conn;
82 }
83 
GetDrmDevice(int display)84 DrmDevice *ResourceManager::GetDrmDevice(int display) {
85   for (auto &drm : drms_) {
86     if (drm->HandlesDisplay(display))
87       return drm.get();
88   }
89   return NULL;
90 }
91 }  // namespace android
92