summaryrefslogtreecommitdiff
path: root/hwc2/common/hdmi/DisplayHdmi.cpp (plain)
blob: f49b826f876e1c5a5a1f5409aed22bd4097af3e7
1//#define LOG_NDEBUG 0
2#include <HwcTrace.h>
3#include <binder/IServiceManager.h>
4#include <utils/Tokenizer.h>
5#include <thread>
6#include <gui/SurfaceComposerClient.h>
7#include <gui/ISurfaceComposer.h>
8#include "DisplayHdmi.h"
9
10namespace android {
11namespace amlogic {
12
13DisplayHdmi::DisplayHdmi(hwc2_display_t id) {
14 mDisplayId = id;
15
16 sp<IServiceManager> sm = defaultServiceManager();
17 if (sm == NULL)
18 {
19 ETRACE("Couldn't get default ServiceManager\n");
20 return ;
21 }
22
23 mSystemControlService = interface_cast<ISystemControlService>(sm->getService(String16("system_control")));
24 if (mSystemControlService == NULL)
25 {
26 ETRACE("Couldn't get connection to SystemControlService\n");
27 return ;
28 }
29
30 initModes();
31}
32
33DisplayHdmi::~DisplayHdmi() {
34 mAllModes.clear();
35}
36
37void DisplayHdmi::initialize() {
38 reset();
39}
40
41void DisplayHdmi::deinitialize() {
42 reset();
43}
44
45void DisplayHdmi::reset() {
46 mConnected = false;
47 mActiveDisplayConfigItem = 0;
48 mActiveRefreshRate = 60;
49 memset(mActiveDisplaymode, 0, HWC_DISPLAY_MODE_LENGTH);
50 mSupportDispModes.clear();
51 for (size_t i = 0; i < mDisplayConfigs.size(); i++) {
52 DisplayConfig *config = mDisplayConfigs[i];
53 if (config)
54 delete config;
55 }
56 mDisplayConfigs.clear();
57}
58
59bool DisplayHdmi::updateHotplug(bool connected,
60 framebuffer_info_t * framebufferInfo,
61 private_handle_t* framebufferHnd) {
62 bool ret = true;
63 int32_t rate;
64
65 mConnected = connected;
66
67 if (!isConnected()) {
68 ETRACE("disp: %d disconnect", (int32_t)mDisplayId);
69 return true;
70 }
71
72 mFramebufferInfo = framebufferInfo;
73 mFramebufferHnd = framebufferHnd;
74
75 if (-1 == updateDisplayModeList()) {
76 //hdmi plug out when system is starting up
77 std::string dispMode;
78 int width, height;
79 mSystemControlService->getActiveDispMode(&dispMode);
80 ret = calcMode2Config(dispMode.c_str(), &rate, &width, &height);
81 if (!ret) {
82 dispMode = std::string("1080p60hz");
83 rate = 60;
84 }
85 ETRACE("only init one display config: %s", dispMode.c_str());
86 strcpy(mActiveDisplaymode, dispMode.c_str());
87
88 // reset display configs
89 for (size_t i = 0; i < mDisplayConfigs.size(); i++) {
90 DisplayConfig *config = mDisplayConfigs[i];
91 if (config)
92 delete config;
93 }
94 mDisplayConfigs.clear();
95
96 // use active fb dimension as config width/height
97 DisplayConfig *config = new DisplayConfig(mActiveDisplaymode,
98 rate,
99 mFramebufferInfo->info.xres,
100 mFramebufferInfo->info.yres,
101 mFramebufferInfo->xdpi,
102 mFramebufferInfo->ydpi);
103 // add it to the front of other configs
104 mDisplayConfigs.push_back(config);
105
106 // init the active display config
107 mActiveDisplayConfigItem = 0;
108 mActiveRefreshRate = rate;
109 //ETRACE("Active display mode %s, refresh rate: %d", mActiveDisplaymode, rate);
110 } else {
111 //hdmi plug in when system is starting up
112 updateActiveDisplayMode();
113 updateDisplayConfigures();
114 updateActiveDisplayConfigure();
115
116 ALOGD("updateHotplug setDisplayMode to %s", mActiveDisplaymode);
117 std::string strmode(mActiveDisplaymode);
118 mSystemControlService->setActiveDispMode(strmode);
119 }
120
121 std::thread t1(&DisplayHdmi::setSurfaceFlingerActiveMode, this);
122 t1.detach();
123
124 return true;
125}
126
127int DisplayHdmi::updateDisplayModeList() {
128 // clear display modes
129 mSupportDispModes.clear();
130
131 bool fullActiveMode = Utils::get_bool_prop("ro.sf.full_activemode");
132 bool isConfiged = readConfigFile("/system/etc/displayModeList.cfg", &mSupportDispModes);
133 if (isConfiged) {
134 return 0;
135 }
136
137 if (!fullActiveMode) {
138 ALOGD("Simple Active Mode!!!");
139 return -1;
140 }
141
142 std::vector<std::string> getSupportDispModes;
143 std::string::size_type pos;
144 mSystemControlService->getSupportDispModeList(&getSupportDispModes);
145 if (getSupportDispModes.size() == 0) {
146 ALOGD("SupportDispModeList null!!!");
147 return -1;
148 }
149
150 for (size_t i = 0; i < getSupportDispModes.size(); i++) {
151 //ALOGD("get support display mode:%s", getSupportDispModes[i].c_str());
152 while (!getSupportDispModes[i].empty()) {
153 pos = getSupportDispModes[i].find('*');
154 if (pos != std::string::npos) {
155 getSupportDispModes[i].erase(pos, 1);
156 //ALOGD("modify support display mode:%s", getSupportDispModes[i].c_str());
157 } else {
158 break;
159 }
160 }
161 }
162
163
164 for (size_t k = 0; k < mAllModes.size(); k++) {
165 for (size_t j = 0; j < getSupportDispModes.size(); j++) {
166 if (!getSupportDispModes[j].empty()) {
167 if (mAllModes[k] == getSupportDispModes[j]) {
168 mSupportDispModes.push_back(getSupportDispModes[j]);
169 ALOGD("support display mode:%s", getSupportDispModes[j].c_str());
170 }
171 }
172 }
173 }
174
175 return 0;
176}
177
178int DisplayHdmi::updateActiveDisplayMode() {
179 std::string dispMode;
180 mSystemControlService->getActiveDispMode(&dispMode);
181 strcpy(mActiveDisplaymode, dispMode.c_str());
182
183 int refreshRate = 60;
184 if (strstr(mActiveDisplaymode, "60hz") != NULL) {
185 refreshRate = 60;
186 } else if (strstr(mActiveDisplaymode, "50hz") != NULL) {
187 refreshRate = 50;
188 } else if (strstr(mActiveDisplaymode, "30hz") != NULL) {
189 refreshRate = 30;
190 } else if (strstr(mActiveDisplaymode, "25hz") != NULL) {
191 refreshRate = 25;
192 } else if ((strstr(mActiveDisplaymode, "24hz") != NULL)
193 || (strstr(mActiveDisplaymode, "smpte") != NULL)) {
194 refreshRate = 24;
195 } else
196 ETRACE("displaymode (%s) doesn't specify HZ", mActiveDisplaymode);
197
198 ALOGD("Active display mode: (%s), refresh rate: (%d)", mActiveDisplaymode, refreshRate);
199
200 mActiveRefreshRate = refreshRate;
201
202 return 0;
203}
204
205int DisplayHdmi::setDisplayMode(const char* displaymode) {
206 ALOGD("setDisplayMode to %s", displaymode);
207
208 std::string strmode(displaymode);
209 mSystemControlService->setActiveDispMode(strmode);
210
211 updateActiveDisplayMode();
212
213 return 0;
214}
215
216int DisplayHdmi::updateDisplayConfigures() {
217 size_t i;
218
219 std::string dispMode;
220 int refreshRate, width, height;
221
222 // reset display configs
223 for (i = 0; i < mDisplayConfigs.size(); i++) {
224 DisplayConfig *config = mDisplayConfigs[i];
225 if (config)
226 delete config;
227 }
228 mDisplayConfigs.clear();
229
230 for (i =0; i < mSupportDispModes.size(); i ++) {
231 dispMode = mSupportDispModes[i];
232 calcMode2Config(dispMode.c_str(), &refreshRate, &width, &height);
233
234 // init dimension as config width/height, set xdpi/ydpi after
235 DisplayConfig *config = new DisplayConfig(dispMode.c_str(),
236 refreshRate, width, height,
237 mFramebufferInfo->xdpi,
238 mFramebufferInfo->ydpi);
239 // add it to the front of other configs
240 mDisplayConfigs.push_back(config);
241 }
242 return 0;
243}
244
245int DisplayHdmi::updateActiveDisplayConfigure() {
246 size_t i;
247
248 DisplayConfig *dispConfig = NULL;
249 for (i = 0; i < mDisplayConfigs.size(); i++) {
250 dispConfig = mDisplayConfigs[i];
251 if (!dispConfig) {
252 continue;
253 }
254 if (0 == strncmp(mActiveDisplaymode, dispConfig->getDisplayMode(),
255 HWC_DISPLAY_MODE_LENGTH-1)) {
256 mActiveDisplayConfigItem = i;
257 ALOGD("updateActiveDisplayConfigure to config(%d)", mActiveDisplayConfigItem);
258 dispConfig->setDpi(mFramebufferInfo->xdpi, mFramebufferInfo->ydpi);
259 break;
260 }
261 }
262 return 0;
263}
264
265int DisplayHdmi::getDisplayConfigs(uint32_t* outNumConfigs,
266 hwc2_config_t* outConfigs) {
267 size_t i;
268
269 if (!isConnected()) {
270 //ETRACE("display %d is not connected.", (int32_t)mDisplayId);
271 }
272
273 for (i = 0; i < mDisplayConfigs.size(); i++) {
274 if (NULL != outConfigs)
275 outConfigs[i] = i;
276 }
277
278 *outNumConfigs = i;
279
280 return HWC2_ERROR_NONE;
281}
282
283int DisplayHdmi::getDisplayAttribute(hwc2_config_t config,
284 int32_t /*hwc2_attribute_t*/ attribute,
285 int32_t* outValue) {
286
287 if (!isConnected()) {
288 //ETRACE("display %d is not connected.", (int32_t)mDisplayId);
289 }
290
291 DisplayConfig *configChosen = mDisplayConfigs[config];
292 if (!configChosen) {
293 ETRACE("failed to get display config: %d", config);
294 return HWC2_ERROR_NONE;
295 }
296
297 switch (attribute) {
298 case HWC2_ATTRIBUTE_VSYNC_PERIOD:
299 if (configChosen->getRefreshRate()) {
300 *outValue = 1e9 / configChosen->getRefreshRate();
301 }
302 break;
303 case HWC2_ATTRIBUTE_WIDTH:
304 *outValue = configChosen->getWidth();
305 break;
306 case HWC2_ATTRIBUTE_HEIGHT:
307 *outValue = configChosen->getHeight();
308 break;
309 case HWC2_ATTRIBUTE_DPI_X:
310 *outValue = configChosen->getDpiX() * 1000.0f;
311 break;
312 case HWC2_ATTRIBUTE_DPI_Y:
313 *outValue = configChosen->getDpiY() * 1000.0f;
314 break;
315 default:
316 ETRACE("unknown display attribute %u", attribute);
317 *outValue = -1;
318 break;
319 }
320
321 return HWC2_ERROR_NONE;
322}
323
324int DisplayHdmi::getActiveConfig(hwc2_config_t* outConfig) {
325 if (!isConnected()) {
326 //ETRACE("display %d is not connected.", (int32_t)mDisplayId);
327 }
328 //ALOGD("getActiveConfig to config(%d).", mActiveDisplayConfigItem);
329 *outConfig = mActiveDisplayConfigItem;
330
331 return HWC2_ERROR_NONE;
332}
333
334int DisplayHdmi::setActiveConfig(int id) {
335 DisplayConfig *dispConfig = NULL;
336 char *dispMode = NULL;
337
338 if (!isConnected()) {
339 //ETRACE("display %d is not connected.", (int32_t)mDisplayId);
340 }
341
342 ALOGD("setActiveConfig to config(%d).", id);
343 mActiveDisplayConfigItem = id;
344 dispConfig = mDisplayConfigs[id];
345 if (!dispConfig) {
346 ETRACE("failed to get display config: %d", id);
347 return HWC2_ERROR_BAD_CONFIG;
348 }
349
350 dispConfig->setDpi(mFramebufferInfo->xdpi,
351 mFramebufferInfo->ydpi);
352
353 dispMode = dispConfig->getDisplayMode();
354 if (!dispMode) {
355 ETRACE("failed to get display mode by config: %d", id);
356 return HWC2_ERROR_BAD_CONFIG;
357 }
358
359 setDisplayMode(dispMode);
360
361 return HWC2_ERROR_NONE;
362}
363
364bool DisplayHdmi::calcMode2Config(const char *dispMode, int* refreshRate,
365 int* width, int* height) {
366
367 if (NULL == dispMode) {
368 ETRACE("dispMode is NULL");
369 return false;
370 }
371
372 if (strstr(dispMode, "60hz") != NULL) {
373 *refreshRate = 60;
374 } else if (strstr(dispMode, "50hz") != NULL) {
375 *refreshRate = 50;
376 } else if (strstr(dispMode, "30hz") != NULL) {
377 *refreshRate = 30;
378 } else if (strstr(dispMode, "25hz") != NULL) {
379 *refreshRate = 25;
380 } else if ((strstr(dispMode, "24hz") != NULL)
381 || (strstr(dispMode, "smpte") != NULL)) {
382 *refreshRate = 24;
383 } else {
384 ETRACE("displaymode (%s) doesn't specify HZ", dispMode);
385 return false;
386 }
387
388 if (strstr(dispMode, "2160") != NULL) {
389 *width = 3840;
390 *height = 2160;
391 } else if (strstr(dispMode, "1080") != NULL) {
392 *width = 1920;
393 *height = 1080;
394 } else if (strstr(dispMode, "720") != NULL) {
395 *width = 1280;
396 *height = 720;
397 } else if (strstr(dispMode, "576") != NULL) {
398 *width = 720;
399 *height = 576;
400 } else if (strstr(dispMode, "480") != NULL) {
401 *width = 640;
402 *height = 480;
403 } else {
404 // smpte and panle imcomplete!!!!!
405 ETRACE("calcMode2Config displaymode (%s) doesn't specify HZ", dispMode);
406 return false;
407 }
408
409 //DTRACE("calcMode2Config (%s) refreshRate(%d), (%dx%d)", dispMode, *refreshRate, *width, *height);
410 return true;
411}
412
413bool DisplayHdmi::readConfigFile(const char* configPath, std::vector<std::string>* supportDispModes) {
414 const char* WHITESPACE = " \t\r";
415
416 Tokenizer* tokenizer;
417 status_t status = Tokenizer::open(String8(configPath), &tokenizer);
418
419 if (status) {
420 DTRACE("Error %d opening display config file %s.", status, configPath);
421 return false;
422 } else {
423 while (!tokenizer->isEof()) {
424 tokenizer->skipDelimiters(WHITESPACE);
425 if (!tokenizer->isEol() && tokenizer->peekChar() != '#') {
426 String8 token = tokenizer->nextToken(WHITESPACE);
427 const char* dispMode = token.string();
428 if (strstr(dispMode, "hz")) {
429 ETRACE("dispMode %s.", dispMode);
430 (*supportDispModes).push_back(std::string(dispMode));
431 }
432 }
433
434 tokenizer->nextLine();
435 }
436 delete tokenizer;
437 }
438
439 size_t num = (*supportDispModes).size();
440
441 if (num <= 0) {
442 return false;
443 } else {
444 return true;
445 }
446}
447
448void DisplayHdmi::setSurfaceFlingerActiveMode() {
449 sp<IBinder> dtoken(SurfaceComposerClient::getBuiltInDisplay(
450 ISurfaceComposer::eDisplayIdMain));
451
452 SurfaceComposerClient::setActiveConfig(dtoken, mDisplayConfigs.size()-mActiveDisplayConfigItem-1);
453
454 return;
455}
456
457void DisplayHdmi::initModes() {
458 //mAllModes.push_back("480p60hz");
459 //mAllModes.push_back("576p50hz");
460 //mAllModes.push_back("720p50hz");
461 //mAllModes.push_back("720p60hz");
462 mAllModes.push_back("1080p60hz");
463 mAllModes.push_back("1080p50hz");
464 mAllModes.push_back("1080p30hz");
465 mAllModes.push_back("1080p25hz");
466 mAllModes.push_back("1080p24hz");
467 //mAllModes.push_back("2160p24hz");
468 //mAllModes.push_back("2160p25hz");
469 //mAllModes.push_back("2160p30hz");
470 //mAllModes.push_back("2160p50hz");
471 //mAllModes.push_back("2160p60hz");
472}
473
474void DisplayHdmi::dump(Dump& d) {
475 d.append(" CONFIG | VSYNC_PERIOD | WIDTH | HEIGHT |"
476 " DPI_X | DPI_Y \n");
477 d.append("------------+------------------+-----------+------------+"
478 "-----------+-----------\n");
479 for (size_t i = 0; i < mDisplayConfigs.size(); i++) {
480 DisplayConfig *config = mDisplayConfigs[i];
481 if (config) {
482 d.append("%s %2d | %4d | %5d | %4d |"
483 " %3d | %3d \n",
484 (i == (size_t)mActiveDisplayConfigItem) ? "* " : " ",
485 i,
486 config->getRefreshRate(),
487 config->getWidth(),
488 config->getHeight(),
489 config->getDpiX(),
490 config->getDpiY());
491 }
492 }
493 }
494
495} // namespace amlogic
496} // namespace android
497
498
499
500