blob: 543e671f15961b01d0a000d561927e3b52af45fe
1 | /* |
2 | * Copyright (c) 2019 Amlogic, Inc. All rights reserved. |
3 | * |
4 | * This source code is subject to the terms and conditions defined in the |
5 | * file 'LICENSE' which is part of this source code package. |
6 | * |
7 | * Description: |
8 | */ |
9 | |
10 | #include <MesonLog.h> |
11 | #include <HwcConfig.h> |
12 | #include <hardware/hwcomposer2.h> |
13 | |
14 | #include "RealModeMgr.h" |
15 | |
16 | #define DEFUALT_DPI (159) |
17 | #define DEFAULT_REFRESH_RATE (60.0f) |
18 | |
19 | static const drm_mode_info_t defaultMode = { |
20 | .name = "null", |
21 | .dpiX = DEFUALT_DPI, |
22 | .dpiY = DEFUALT_DPI, |
23 | .pixelW = 720, |
24 | .pixelH = 480, |
25 | .refreshRate = DEFAULT_REFRESH_RATE, |
26 | }; |
27 | |
28 | RealModeMgr::RealModeMgr() { |
29 | mCallOnHotPlug = true; |
30 | } |
31 | |
32 | RealModeMgr::~RealModeMgr() { |
33 | } |
34 | |
35 | hwc_modes_policy_t RealModeMgr::getPolicyType() { |
36 | return REAL_MODE_POLICY; |
37 | } |
38 | |
39 | const char * RealModeMgr::getName() { |
40 | return "RealModeMgr"; |
41 | } |
42 | |
43 | void RealModeMgr::setFramebufferSize(uint32_t w, uint32_t h) { |
44 | mHwcFbWidth = w; |
45 | mHwcFbHeight =h; |
46 | } |
47 | |
48 | void RealModeMgr::setDisplayResources( |
49 | std::shared_ptr<HwDisplayCrtc> & crtc, |
50 | std::shared_ptr<HwDisplayConnector> & connector) { |
51 | mConnector = connector; |
52 | mCrtc = crtc; |
53 | } |
54 | |
55 | int32_t RealModeMgr::updateActiveConfig(const char* activeMode) { |
56 | for (auto it = mModes.begin(); it != mModes.end(); ++it) { |
57 | if (strncmp(activeMode, it->second.name, DRM_DISPLAY_MODE_LEN) == 0) { |
58 | mActiveConfigId = it->first; |
59 | MESON_LOGV("updateActiveConfig aciveConfigId = %d", mActiveConfigId); |
60 | return HWC2_ERROR_NONE; |
61 | } |
62 | } |
63 | |
64 | mActiveConfigId = mModes.size()-1; |
65 | MESON_LOGD("%s something error to (%s, %d)", __func__, activeMode, mActiveConfigId); |
66 | |
67 | return HWC2_ERROR_NONE; |
68 | } |
69 | |
70 | void RealModeMgr::reset() { |
71 | mModes.clear(); |
72 | mActiveConfigId = -1; |
73 | } |
74 | |
75 | int32_t RealModeMgr::update() { |
76 | std::lock_guard<std::mutex> lock(mMutex); |
77 | bool useFakeMode = true; |
78 | drm_mode_info_t realMode; |
79 | std::map<uint32_t, drm_mode_info_t> supportModes; |
80 | |
81 | #ifdef HWC_SUPPORT_MODES_LIST |
82 | /* reset ModeList */ |
83 | reset(); |
84 | #endif |
85 | if (mConnector->isConnected()) { |
86 | mConnector->getModes(supportModes); |
87 | if (mCrtc->getMode(realMode) == 0) { |
88 | if (realMode.name[0] != 0) { |
89 | mCurMode = realMode; |
90 | useFakeMode = false; |
91 | } |
92 | } |
93 | |
94 | #ifdef HWC_SUPPORT_MODES_LIST |
95 | for (auto it = supportModes.begin(); it != supportModes.end(); it++) { |
96 | mModes.emplace(mModes.size(), it->second); |
97 | } |
98 | #endif |
99 | } |
100 | |
101 | if (useFakeMode) { |
102 | mCurMode = defaultMode; |
103 | #ifdef HWC_SUPPORT_MODES_LIST |
104 | mModes.emplace(mModes.size(), mCurMode); |
105 | #endif |
106 | } |
107 | |
108 | #ifdef HWC_SUPPORT_MODES_LIST |
109 | updateActiveConfig(mCurMode.name); |
110 | #endif |
111 | |
112 | return HWC2_ERROR_NONE; |
113 | } |
114 | |
115 | int32_t RealModeMgr::getDisplayMode(drm_mode_info_t & mode) { |
116 | return mCrtc->getMode(mode); |
117 | } |
118 | |
119 | int32_t RealModeMgr::getDisplayConfigs( |
120 | uint32_t * outNumConfigs, uint32_t * outConfigs) { |
121 | std::lock_guard<std::mutex> lock(mMutex); |
122 | #ifdef HWC_SUPPORT_MODES_LIST |
123 | *outNumConfigs = mModes.size(); |
124 | |
125 | if (outConfigs) { |
126 | std::map<uint32_t, drm_mode_info_t>::iterator it = |
127 | mModes.begin(); |
128 | for (uint32_t index = 0; it != mModes.end(); ++it, ++index) { |
129 | outConfigs[index] = it->first; |
130 | MESON_LOGV("realmode getDisplayConfigs outConfig[%d]: %d %s.", index, outConfigs[index], it->second.name); |
131 | } |
132 | } |
133 | #else |
134 | *outNumConfigs = 1; |
135 | if (outConfigs) |
136 | *outConfigs = 0; |
137 | #endif |
138 | return HWC2_ERROR_NONE; |
139 | } |
140 | |
141 | int32_t RealModeMgr::getDisplayAttribute( |
142 | uint32_t config, int32_t attribute, int32_t * outValue, |
143 | int32_t caller __unused) { |
144 | std::lock_guard<std::mutex> lock(mMutex); |
145 | #ifdef HWC_SUPPORT_MODES_LIST |
146 | std::map<uint32_t, drm_mode_info_t>::iterator it; |
147 | it = mModes.find(config); |
148 | |
149 | if (it != mModes.end()) { |
150 | drm_mode_info_t curMode = it->second; |
151 | #else |
152 | UNUSED(config); |
153 | drm_mode_info_t curMode = mCurMode; |
154 | #endif |
155 | switch (attribute) { |
156 | case HWC2_ATTRIBUTE_WIDTH: |
157 | *outValue = curMode.pixelW; |
158 | break; |
159 | case HWC2_ATTRIBUTE_HEIGHT: |
160 | *outValue = curMode.pixelH; |
161 | break; |
162 | case HWC2_ATTRIBUTE_VSYNC_PERIOD: |
163 | if (HwcConfig::isHeadlessMode()) { |
164 | *outValue = 1e9 / HwcConfig::headlessRefreshRate(); |
165 | } else { |
166 | *outValue = 1e9 / curMode.refreshRate; |
167 | } |
168 | break; |
169 | case HWC2_ATTRIBUTE_DPI_X: |
170 | *outValue = curMode.dpiX * 1000.0f; |
171 | break; |
172 | case HWC2_ATTRIBUTE_DPI_Y: |
173 | *outValue = curMode.dpiY * 1000.0f; |
174 | break; |
175 | default: |
176 | MESON_LOGE("Unkown display attribute(%d)", attribute); |
177 | break; |
178 | } |
179 | #ifdef HWC_SUPPORT_MODES_LIST |
180 | } else { |
181 | MESON_LOGE("[%s]: no support display config: %d", __func__, config); |
182 | return HWC2_ERROR_UNSUPPORTED; |
183 | } |
184 | #endif |
185 | |
186 | return HWC2_ERROR_NONE; |
187 | } |
188 | |
189 | int32_t RealModeMgr::getActiveConfig(uint32_t * outConfig, int32_t caller __unused) { |
190 | std::lock_guard<std::mutex> lock(mMutex); |
191 | #ifdef HWC_SUPPORT_MODES_LIST |
192 | *outConfig = mActiveConfigId; |
193 | #else |
194 | *outConfig = 0; |
195 | #endif |
196 | MESON_LOGV("[%s] ActiveConfigid=%d", __func__, *outConfig); |
197 | |
198 | return HWC2_ERROR_NONE; |
199 | } |
200 | |
201 | int32_t RealModeMgr::setActiveConfig(uint32_t config) { |
202 | std::lock_guard<std::mutex> lock(mMutex); |
203 | #ifdef HWC_SUPPORT_MODES_LIST |
204 | std::map<uint32_t, drm_mode_info_t>::iterator it = |
205 | mModes.find(config); |
206 | |
207 | MESON_LOGV("[%s] %d", __func__, config); |
208 | if (it != mModes.end()) { |
209 | drm_mode_info_t cfg = it->second; |
210 | |
211 | updateActiveConfig(cfg.name); |
212 | if (strncmp(cfg.name, defaultMode.name, DRM_DISPLAY_MODE_LEN) == 0) { |
213 | MESON_LOGD("setActiveConfig default mode not supported"); |
214 | return HWC2_ERROR_NONE; |
215 | } |
216 | |
217 | mCallOnHotPlug = false; |
218 | mConnector->setMode(cfg); |
219 | mCrtc->setMode(cfg); |
220 | } else { |
221 | MESON_LOGE("set invalild active config (%d)", config); |
222 | return HWC2_ERROR_NOT_VALIDATED; |
223 | } |
224 | #else |
225 | if (config > 0) |
226 | MESON_LOGE("RealModeMgr not support config (%d)", config); |
227 | #endif |
228 | |
229 | return HWC2_ERROR_NONE; |
230 | } |
231 | |
232 | void RealModeMgr::resetTags() { |
233 | mCallOnHotPlug = true; |
234 | }; |
235 | |
236 | void RealModeMgr::dump(String8 & dumpstr) { |
237 | dumpstr.appendFormat("RealModeMgr:(%s)\n", mCurMode.name); |
238 | dumpstr.append("---------------------------------------------------------" |
239 | "-------------------------------------\n"); |
240 | dumpstr.append("| CONFIG | VSYNC_PERIOD | WIDTH | HEIGHT |" |
241 | " DPI_X | DPI_Y | NAME |\n"); |
242 | dumpstr.append("+------------+------------------+-----------+------------+" |
243 | "-----------+-----------+-----------+\n"); |
244 | |
245 | #ifdef HWC_SUPPORT_MODES_LIST |
246 | std::map<uint32_t, drm_mode_info_t>::iterator it = |
247 | mModes.begin(); |
248 | |
249 | for (; it != mModes.end(); ++it) { |
250 | int mode = it->first; |
251 | drm_mode_info_t config = it->second; |
252 | #else |
253 | int mode = 0; |
254 | mActiveConfigId = 0; |
255 | drm_mode_info_t config = mCurMode; |
256 | #endif |
257 | dumpstr.appendFormat("%s %2d | %.3f | %5d | %5d |" |
258 | " %3d | %3d | %10s |\n", |
259 | (mode == (int)mActiveConfigId) ? "* " : " ", |
260 | mode, |
261 | config.refreshRate, |
262 | config.pixelW, |
263 | config.pixelH, |
264 | config.dpiX, |
265 | config.dpiY, |
266 | config.name); |
267 | #ifdef HWC_SUPPORT_MODES_LIST |
268 | } |
269 | #endif |
270 | dumpstr.append("---------------------------------------------------------" |
271 | "-------------------------------------\n"); |
272 | } |
273 |