1 /*
2 * Copyright (C) 2012 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 #include "ExynosHWCService.h"
18
19 #include <chrono>
20
21 #include "ExynosExternalDisplay.h"
22 #include "ExynosVirtualDisplay.h"
23 #include "ExynosVirtualDisplayModule.h"
24 #define HWC_SERVICE_DEBUG 0
25
26 namespace android {
27
28 ANDROID_SINGLETON_STATIC_INSTANCE(ExynosHWCService);
29
ExynosHWCService()30 ExynosHWCService::ExynosHWCService()
31 : mHWCService(NULL), mHWCCtx(NULL), bootFinishedCallback(NULL) {
32 ALOGD_IF(HWC_SERVICE_DEBUG, "ExynosHWCService Constructor is called");
33 }
34
~ExynosHWCService()35 ExynosHWCService::~ExynosHWCService()
36 {
37 ALOGD_IF(HWC_SERVICE_DEBUG, "ExynosHWCService Destructor is called");
38 }
39
addVirtualDisplayDevice()40 int ExynosHWCService::addVirtualDisplayDevice()
41 {
42 ALOGD_IF(HWC_SERVICE_DEBUG, "%s", __func__);
43
44 mHWCCtx->device->mNumVirtualDisplay++;
45
46 return NO_ERROR;
47 }
48
destroyVirtualDisplayDevice()49 int ExynosHWCService::destroyVirtualDisplayDevice()
50 {
51 ALOGD_IF(HWC_SERVICE_DEBUG, "%s", __func__);
52
53 mHWCCtx->device->mNumVirtualDisplay--;
54
55 return NO_ERROR;
56 }
57
setWFDMode(unsigned int mode)58 int ExynosHWCService::setWFDMode(unsigned int mode)
59 {
60 ALOGD_IF(HWC_SERVICE_DEBUG, "%s::mode=%d", __func__, mode);
61 for (uint32_t i = 0; i < mHWCCtx->device->mDisplays.size(); i++) {
62 if (mHWCCtx->device->mDisplays[i]->mType == HWC_DISPLAY_VIRTUAL) {
63 ExynosVirtualDisplay *virtualdisplay =
64 (ExynosVirtualDisplay *)mHWCCtx->device->mDisplays[i];
65 return virtualdisplay->setWFDMode(mode);
66 }
67 }
68 return INVALID_OPERATION;
69 }
70
getWFDMode()71 int ExynosHWCService::getWFDMode()
72 {
73 ALOGD_IF(HWC_SERVICE_DEBUG, "%s", __func__);
74 for (uint32_t i = 0; i < mHWCCtx->device->mDisplays.size(); i++) {
75 if (mHWCCtx->device->mDisplays[i]->mType == HWC_DISPLAY_VIRTUAL) {
76 ExynosVirtualDisplay *virtualdisplay =
77 (ExynosVirtualDisplay *)mHWCCtx->device->mDisplays[i];
78 return virtualdisplay->getWFDMode();
79 }
80 }
81 return INVALID_OPERATION;
82 }
83
sendWFDCommand(int32_t cmd,int32_t ext1,int32_t ext2)84 int ExynosHWCService::sendWFDCommand(int32_t cmd, int32_t ext1, int32_t ext2)
85 {
86 ALOGD_IF(HWC_SERVICE_DEBUG, "%s::cmd=%d, ext1=%d, ext2=%d", __func__, cmd, ext1, ext2);
87 for (uint32_t i = 0; i < mHWCCtx->device->mDisplays.size(); i++) {
88 if (mHWCCtx->device->mDisplays[i]->mType == HWC_DISPLAY_VIRTUAL) {
89 ExynosVirtualDisplay *virtualdisplay =
90 (ExynosVirtualDisplay *)mHWCCtx->device->mDisplays[i];
91 return virtualdisplay->sendWFDCommand(cmd, ext1, ext2);
92 }
93 }
94 return INVALID_OPERATION;
95 }
96
setSecureVDSMode(unsigned int mode)97 int ExynosHWCService::setSecureVDSMode(unsigned int mode)
98 {
99 ALOGD_IF(HWC_SERVICE_DEBUG, "%s::mode=%d", __func__, mode);
100 for (uint32_t i = 0; i < mHWCCtx->device->mDisplays.size(); i++) {
101 if (mHWCCtx->device->mDisplays[i]->mType == HWC_DISPLAY_VIRTUAL) {
102 ExynosVirtualDisplay *virtualdisplay =
103 (ExynosVirtualDisplay *)mHWCCtx->device->mDisplays[i];
104 return virtualdisplay->setSecureVDSMode(mode);
105 }
106 }
107 return INVALID_OPERATION;
108 }
109
setWFDOutputResolution(unsigned int width,unsigned int height)110 int ExynosHWCService::setWFDOutputResolution(unsigned int width, unsigned int height)
111 {
112 ALOGD_IF(HWC_SERVICE_DEBUG, "%s::width=%d, height=%d", __func__, width, height);
113
114 for (uint32_t i = 0; i < mHWCCtx->device->mDisplays.size(); i++) {
115 if (mHWCCtx->device->mDisplays[i]->mType == HWC_DISPLAY_VIRTUAL) {
116 ExynosVirtualDisplay *virtualdisplay =
117 (ExynosVirtualDisplay *)mHWCCtx->device->mDisplays[i];
118 return virtualdisplay->setWFDOutputResolution(width, height);
119 }
120 }
121 return INVALID_OPERATION;
122 }
123
getWFDOutputResolution(unsigned int * width,unsigned int * height)124 void ExynosHWCService::getWFDOutputResolution(unsigned int *width, unsigned int *height)
125 {
126 ALOGD_IF(HWC_SERVICE_DEBUG, "%s", __func__);
127 for (uint32_t i = 0; i < mHWCCtx->device->mDisplays.size(); i++) {
128 if (mHWCCtx->device->mDisplays[i]->mType == HWC_DISPLAY_VIRTUAL) {
129 ExynosVirtualDisplay *virtualdisplay =
130 (ExynosVirtualDisplay *)mHWCCtx->device->mDisplays[i];
131 virtualdisplay->getWFDOutputResolution(width, height);
132 return;
133 }
134 }
135 }
136
setPresentationMode(bool use)137 void ExynosHWCService::setPresentationMode(bool use)
138 {
139 ALOGD_IF(HWC_SERVICE_DEBUG, "%s::PresentationMode=%s", __func__, use == false ? "false" : "true");
140 for (uint32_t i = 0; i < mHWCCtx->device->mDisplays.size(); i++) {
141 if (mHWCCtx->device->mDisplays[i]->mType == HWC_DISPLAY_VIRTUAL) {
142 ExynosVirtualDisplay *virtualdisplay =
143 (ExynosVirtualDisplay *)mHWCCtx->device->mDisplays[i];
144 virtualdisplay->setPresentationMode(!!use);
145 return;
146 }
147 }
148 }
149
getPresentationMode()150 int ExynosHWCService::getPresentationMode()
151 {
152 ALOGD_IF(HWC_SERVICE_DEBUG, "%s", __func__);
153 for (uint32_t i = 0; i < mHWCCtx->device->mDisplays.size(); i++) {
154 if (mHWCCtx->device->mDisplays[i]->mType == HWC_DISPLAY_VIRTUAL) {
155 ExynosVirtualDisplay *virtualdisplay =
156 (ExynosVirtualDisplay *)mHWCCtx->device->mDisplays[i];
157 return virtualdisplay->getPresentationMode();
158 }
159 }
160 return INVALID_OPERATION;
161 }
162
setVDSGlesFormat(int format)163 int ExynosHWCService::setVDSGlesFormat(int format)
164 {
165 ALOGD_IF(HWC_SERVICE_DEBUG, "%s::format=%d", __func__, format);
166
167 for (uint32_t i = 0; i < mHWCCtx->device->mDisplays.size(); i++) {
168 if (mHWCCtx->device->mDisplays[i]->mType == HWC_DISPLAY_VIRTUAL) {
169 ExynosVirtualDisplay *virtualdisplay =
170 (ExynosVirtualDisplay *)mHWCCtx->device->mDisplays[i];
171 return virtualdisplay->setVDSGlesFormat(format);
172 }
173 }
174
175 return INVALID_OPERATION;
176 }
177
getExternalDisplayConfigs()178 int ExynosHWCService::getExternalDisplayConfigs()
179 {
180 ALOGD_IF(HWC_SERVICE_DEBUG, "%s", __func__);
181
182 ExynosExternalDisplay *external_display =
183 (ExynosExternalDisplay *)mHWCCtx->device->getDisplay(getDisplayId(HWC_DISPLAY_EXTERNAL, 0));
184
185 if ((external_display != nullptr) &&
186 (external_display->mHpdStatus == true)) {
187 external_display->mDisplayInterface->dumpDisplayConfigs();
188 }
189
190 return NO_ERROR;
191 }
192
setExternalDisplayConfig(unsigned int index)193 int ExynosHWCService::setExternalDisplayConfig(unsigned int index)
194 {
195 ALOGD_IF(HWC_SERVICE_DEBUG, "%s::config=%d", __func__, index);
196
197 ExynosExternalDisplay *external_display =
198 (ExynosExternalDisplay *)mHWCCtx->device->getDisplay(getDisplayId(HWC_DISPLAY_EXTERNAL, 0));
199
200 if ((external_display != nullptr) &&
201 (external_display->mHpdStatus == true)) {
202 external_display->setActiveConfig(index);
203 }
204
205 return NO_ERROR;
206 }
207
setExternalVsyncEnabled(unsigned int index)208 int ExynosHWCService::setExternalVsyncEnabled(unsigned int index)
209 {
210 ALOGD_IF(HWC_SERVICE_DEBUG, "%s::config=%d", __func__, index);
211
212 mHWCCtx->device->mVsyncDisplayId = index;
213 ExynosExternalDisplay *external_display =
214 (ExynosExternalDisplay *)mHWCCtx->device->getDisplay(getDisplayId(HWC_DISPLAY_EXTERNAL, 0));
215 if (external_display != nullptr)
216 external_display->setVsyncEnabled(index);
217
218 return NO_ERROR;
219 }
220
getExternalHdrCapabilities()221 int ExynosHWCService::getExternalHdrCapabilities()
222 {
223 ALOGD_IF(HWC_SERVICE_DEBUG, "%s", __func__);
224
225 ExynosExternalDisplay *external_display =
226 (ExynosExternalDisplay *)mHWCCtx->device->getDisplay(getDisplayId(HWC_DISPLAY_EXTERNAL, 0));
227
228 if (external_display != nullptr)
229 return external_display->mExternalHdrSupported;
230 return 0;
231 }
232
setBootFinishedCallback(void (* callback)(ExynosHWCCtx *))233 void ExynosHWCService::setBootFinishedCallback(void (*callback)(ExynosHWCCtx *))
234 {
235 ALOGD_IF(HWC_SERVICE_DEBUG, "%s, callback %p", __func__, callback);
236 bootFinishedCallback = callback;
237 }
238
setBootFinished()239 void ExynosHWCService::setBootFinished() {
240 ALOGD_IF(HWC_SERVICE_DEBUG, "%s", __func__);
241 if (bootFinishedCallback != NULL)
242 bootFinishedCallback(mHWCCtx);
243 }
244
enableMPP(uint32_t physicalType,uint32_t physicalIndex,uint32_t logicalIndex,uint32_t enable)245 void ExynosHWCService::enableMPP(uint32_t physicalType, uint32_t physicalIndex, uint32_t logicalIndex, uint32_t enable)
246 {
247 ALOGD("%s:: type(%d), index(%d, %d), enable(%d)",
248 __func__, physicalType, physicalIndex, logicalIndex, enable);
249 ExynosResourceManager::enableMPP(physicalType, physicalIndex, logicalIndex, enable);
250 mHWCCtx->device->setGeometryChanged(GEOMETRY_DEVICE_CONFIG_CHANGED);
251 mHWCCtx->device->onRefreshDisplays();
252 }
253
setScaleDownRatio(uint32_t physicalType,uint32_t physicalIndex,uint32_t logicalIndex,uint32_t scaleDownRatio)254 void ExynosHWCService::setScaleDownRatio(uint32_t physicalType,
255 uint32_t physicalIndex, uint32_t logicalIndex, uint32_t scaleDownRatio)
256 {
257 ALOGD("%s:: type(%d), index(%d, %d), scaleDownRatio(%d)",
258 __func__, physicalType, physicalIndex, logicalIndex, scaleDownRatio);
259 ExynosResourceManager::setScaleDownRatio(physicalType, physicalIndex, logicalIndex, scaleDownRatio);
260 mHWCCtx->device->setGeometryChanged(GEOMETRY_DEVICE_CONFIG_CHANGED);
261 mHWCCtx->device->onRefreshDisplays();
262 }
263
setLbeCtrl(uint32_t display_id,uint32_t state,uint32_t lux)264 void ExynosHWCService::setLbeCtrl(uint32_t display_id, uint32_t state, uint32_t lux) {
265 ALOGD("%s:: display_id(%d), state(%d), lux(%d)", __func__, display_id, state, lux);
266 if (mHWCCtx) {
267 auto display = mHWCCtx->device->getDisplay(display_id);
268
269 if (display != nullptr) {
270 display->setLbeState(static_cast<LbeState>(state));
271 display->setLbeAmbientLight(lux);
272 }
273 }
274 }
275
setHWCDebug(int debug)276 void ExynosHWCService::setHWCDebug(int debug)
277 {
278 ALOGD_IF(HWC_SERVICE_DEBUG, "%s, debug %d", __func__, debug);
279 mHWCCtx->device->setHWCDebug(debug);
280 }
281
getHWCDebug()282 uint32_t ExynosHWCService::getHWCDebug()
283 {
284 ALOGD_IF(HWC_SERVICE_DEBUG, "%s", __func__);
285 return mHWCCtx->device->getHWCDebug();
286 }
287
setHWCFenceDebug(uint32_t fenceNum,uint32_t ipNum,uint32_t mode)288 void ExynosHWCService::setHWCFenceDebug(uint32_t fenceNum, uint32_t ipNum, uint32_t mode)
289 {
290 ALOGD_IF(HWC_SERVICE_DEBUG, "%s", __func__);
291 mHWCCtx->device->setHWCFenceDebug(fenceNum, ipNum, mode);
292 }
293
getHWCFenceDebug()294 void ExynosHWCService::getHWCFenceDebug()
295 {
296 ALOGD_IF(HWC_SERVICE_DEBUG, "%s", __func__);
297 mHWCCtx->device->getHWCFenceDebug();
298 }
299
setHWCCtl(uint32_t display,uint32_t ctrl,int32_t val)300 int ExynosHWCService::setHWCCtl(uint32_t display, uint32_t ctrl, int32_t val)
301 {
302 int err = 0;
303 switch (ctrl) {
304 case HWC_CTL_FORCE_GPU:
305 case HWC_CTL_WINDOW_UPDATE:
306 case HWC_CTL_FORCE_PANIC:
307 case HWC_CTL_SKIP_STATIC:
308 case HWC_CTL_SKIP_M2M_PROCESSING:
309 case HWC_CTL_SKIP_RESOURCE_ASSIGN:
310 case HWC_CTL_SKIP_VALIDATE:
311 case HWC_CTL_DUMP_MID_BUF:
312 case HWC_CTL_CAPTURE_READBACK:
313 case HWC_CTL_ENABLE_COMPOSITION_CROP:
314 case HWC_CTL_ENABLE_EXYNOSCOMPOSITION_OPT:
315 case HWC_CTL_ENABLE_CLIENTCOMPOSITION_OPT:
316 case HWC_CTL_USE_MAX_G2D_SRC:
317 case HWC_CTL_ENABLE_HANDLE_LOW_FPS:
318 case HWC_CTL_ENABLE_EARLY_START_MPP:
319 case HWC_CTL_DISPLAY_MODE:
320 case HWC_CTL_DDI_RESOLUTION_CHANGE:
321 case HWC_CTL_DYNAMIC_RECOMP:
322 case HWC_CTL_ENABLE_FENCE_TRACER:
323 case HWC_CTL_SYS_FENCE_LOGGING:
324 case HWC_CTL_DO_FENCE_FILE_DUMP:
325 ALOGI("%s::%d on/off=%d", __func__, ctrl, val);
326 mHWCCtx->device->setHWCControl(display, ctrl, val);
327 break;
328 default:
329 ALOGE("%s: unsupported HWC_CTL, (%d)", __func__, ctrl);
330 err = -1;
331 break;
332 }
333 return err;
334 }
335
setDDIScaler(uint32_t display_id,uint32_t width,uint32_t height)336 int ExynosHWCService::setDDIScaler(uint32_t display_id, uint32_t width, uint32_t height) {
337 ALOGD_IF(HWC_SERVICE_DEBUG, "%s, width=%d, height=%d", __func__, width, height);
338 if (mHWCCtx) {
339 ExynosDisplay *display = (ExynosDisplay *)mHWCCtx->device->getDisplay(display_id);
340
341 if (display == NULL)
342 return -EINVAL;
343
344 display->setDDIScalerEnable(width, height);
345 return NO_ERROR;
346 } else {
347 ALOGE_IF(HWC_SERVICE_DEBUG, "Service is not exist");
348 return -EINVAL;
349 }
350 }
351
createServiceLocked()352 int ExynosHWCService::createServiceLocked()
353 {
354 ALOGD_IF(HWC_SERVICE_DEBUG, "%s::", __func__);
355 sp<IServiceManager> sm = defaultServiceManager();
356 sm->addService(String16("Exynos.HWCService"), mHWCService, false);
357 if (sm->checkService(String16("Exynos.HWCService")) != NULL) {
358 ALOGD_IF(HWC_SERVICE_DEBUG, "adding Exynos.HWCService succeeded");
359 return 0;
360 } else {
361 ALOGE_IF(HWC_SERVICE_DEBUG, "adding Exynos.HWCService failed");
362 return -1;
363 }
364 }
365
getExynosHWCService()366 ExynosHWCService *ExynosHWCService::getExynosHWCService()
367 {
368 ALOGD_IF(HWC_SERVICE_DEBUG, "%s::", __func__);
369 ExynosHWCService& instance = ExynosHWCService::getInstance();
370 Mutex::Autolock _l(instance.mLock);
371 if (instance.mHWCService == NULL) {
372 instance.mHWCService = &instance;
373 int status = ExynosHWCService::getInstance().createServiceLocked();
374 if (status != 0) {
375 ALOGE_IF(HWC_SERVICE_DEBUG, "getExynosHWCService failed");
376 }
377 }
378 return instance.mHWCService;
379 }
380
setExynosHWCCtx(ExynosHWCCtx * HWCCtx)381 void ExynosHWCService::setExynosHWCCtx(ExynosHWCCtx *HWCCtx)
382 {
383 ALOGD_IF(HWC_SERVICE_DEBUG, "%s, HWCCtx=%p", __func__, HWCCtx);
384 if(HWCCtx) {
385 mHWCCtx = HWCCtx;
386 }
387 }
388
setDisplayDeviceMode(int32_t display_id,int32_t mode)389 int32_t ExynosHWCService::setDisplayDeviceMode(int32_t display_id, int32_t mode)
390 {
391 return mHWCCtx->device->setDisplayDeviceMode(display_id, mode);
392 }
393
setPanelGammaTableSource(int32_t display_id,int32_t type,int32_t source)394 int32_t ExynosHWCService::setPanelGammaTableSource(int32_t display_id, int32_t type,
395 int32_t source) {
396 return mHWCCtx->device->setPanelGammaTableSource(display_id, type, source);
397 }
398
setDisplayBrightness(int32_t display_id,float brightness)399 int32_t ExynosHWCService::setDisplayBrightness(int32_t display_id, float brightness) {
400 if (brightness < 0 || brightness > 1.0)
401 return -EINVAL;
402
403 auto display = mHWCCtx->device->getDisplay(display_id);
404
405 if (display != nullptr)
406 return display->setDisplayBrightness(brightness);
407
408 return -EINVAL;
409 }
410
ignoreDisplayBrightnessUpdateRequests(int32_t displayId,bool ignore)411 int32_t ExynosHWCService::ignoreDisplayBrightnessUpdateRequests(int32_t displayId, bool ignore) {
412 ALOGD("ExynosHWCService::%s() displayId(%u) ignore(%u)", __func__, displayId, ignore);
413
414 auto display = mHWCCtx->device->getDisplay(displayId);
415
416 if (display != nullptr)
417 return display->ignoreBrightnessUpdateRequests(ignore);
418
419 return -EINVAL;
420 }
421
setDisplayBrightnessNits(const int32_t display_id,const float nits)422 int32_t ExynosHWCService::setDisplayBrightnessNits(const int32_t display_id, const float nits) {
423 if (nits < 0)
424 return -EINVAL;
425
426 auto display = mHWCCtx->device->getDisplay(display_id);
427
428 if (display != nullptr)
429 return display->setBrightnessNits(nits);
430
431 return -EINVAL;
432 }
433
setDisplayBrightnessDbv(int32_t display_id,uint32_t dbv)434 int32_t ExynosHWCService::setDisplayBrightnessDbv(int32_t display_id, uint32_t dbv) {
435 auto display = mHWCCtx->device->getDisplay(display_id);
436
437 if (display != nullptr) {
438 return display->setBrightnessDbv(dbv);
439 } else {
440 ALOGE("ExynosHWCService::%s() invalid display id: %d\n", __func__, display_id);
441 }
442
443 return -EINVAL;
444 }
445
setDisplayLhbm(int32_t display_id,uint32_t on)446 int32_t ExynosHWCService::setDisplayLhbm(int32_t display_id, uint32_t on) {
447 if (on > 1) return -EINVAL;
448
449 auto display = mHWCCtx->device->getDisplay(display_id);
450
451 if (display != nullptr) {
452 display->setLhbmState(!!on);
453 return NO_ERROR;
454 }
455
456 return -EINVAL;
457 }
458
setMinIdleRefreshRate(uint32_t display_id,int32_t fps)459 int32_t ExynosHWCService::setMinIdleRefreshRate(uint32_t display_id, int32_t fps) {
460 ALOGD("ExynosHWCService::%s() display_id(%u) fps(%d)", __func__, display_id, fps);
461
462 auto display = mHWCCtx->device->getDisplay(display_id);
463
464 if (display != nullptr) {
465 return display->setMinIdleRefreshRate(fps, VrrThrottleRequester::TEST);
466 }
467
468 return -EINVAL;
469 }
470
setRefreshRateThrottle(uint32_t display_id,int32_t delayMs)471 int32_t ExynosHWCService::setRefreshRateThrottle(uint32_t display_id, int32_t delayMs) {
472 ALOGD("ExynosHWCService::%s() display_id(%u) delayMs(%d)", __func__, display_id, delayMs);
473
474 auto display = mHWCCtx->device->getDisplay(display_id);
475
476 if (display != nullptr) {
477 return display
478 ->setRefreshRateThrottleNanos(std::chrono::duration_cast<std::chrono::nanoseconds>(
479 std::chrono::milliseconds(delayMs))
480 .count(),
481 VrrThrottleRequester::TEST);
482 }
483
484 return -EINVAL;
485 }
486
setDisplayRCDLayerEnabled(uint32_t displayIndex,bool enable)487 int32_t ExynosHWCService::setDisplayRCDLayerEnabled(uint32_t displayIndex, bool enable) {
488 ALOGD("ExynosHWCService::%s() displayIndex(%u) enable(%u)", __func__, displayIndex, enable);
489
490 auto primaryDisplay =
491 mHWCCtx->device->getDisplay(getDisplayId(HWC_DISPLAY_PRIMARY, displayIndex));
492 if (primaryDisplay == nullptr) return -EINVAL;
493
494 auto ret = primaryDisplay->setDebugRCDLayerEnabled(enable);
495
496 mHWCCtx->device->setGeometryChanged(GEOMETRY_DEVICE_CONFIG_CHANGED);
497 mHWCCtx->device->onRefresh(getDisplayId(HWC_DISPLAY_PRIMARY, displayIndex));
498
499 return ret;
500 }
501
triggerDisplayIdleEnter(uint32_t displayIndex,uint32_t idleTeRefreshRate)502 int32_t ExynosHWCService::triggerDisplayIdleEnter(uint32_t displayIndex,
503 uint32_t idleTeRefreshRate) {
504 ALOGD("ExynosHWCService::%s() displayIndex(%u) idleTeRefreshRate(%u)", __func__, displayIndex,
505 idleTeRefreshRate);
506
507 auto primaryDisplay =
508 mHWCCtx->device->getDisplay(getDisplayId(HWC_DISPLAY_PRIMARY, displayIndex));
509 if (primaryDisplay == nullptr) return -EINVAL;
510
511 mHWCCtx->device->onVsyncIdle(primaryDisplay->getId());
512 primaryDisplay->handleDisplayIdleEnter(idleTeRefreshRate);
513
514 return NO_ERROR;
515 }
516
setDisplayDbm(int32_t display_id,uint32_t on)517 int32_t ExynosHWCService::setDisplayDbm(int32_t display_id, uint32_t on) {
518 if (on > 1) return -EINVAL;
519
520 auto display = mHWCCtx->device->getDisplay(display_id);
521
522 if (display == nullptr) return -EINVAL;
523
524 ALOGD("ExynosHWCService::%s() display(%u) on=%d", __func__, display_id, on);
525 display->setDbmState(!!on);
526 mHWCCtx->device->onRefresh(display_id);
527 return NO_ERROR;
528 }
529
setDisplayMultiThreadedPresent(const int32_t & displayId,const bool & enable)530 int32_t ExynosHWCService::setDisplayMultiThreadedPresent(const int32_t& displayId,
531 const bool& enable) {
532 auto display = mHWCCtx->device->getDisplay(displayId);
533
534 if (display == nullptr) return -EINVAL;
535
536 display->mDisplayControl.multiThreadedPresent = enable;
537 ALOGD("ExynosHWCService::%s() display(%u) enable=%d", __func__, displayId, enable);
538 return NO_ERROR;
539 }
540
triggerRefreshRateIndicatorUpdate(uint32_t displayId,uint32_t refreshRate)541 int32_t ExynosHWCService::triggerRefreshRateIndicatorUpdate(uint32_t displayId,
542 uint32_t refreshRate) {
543 auto display = mHWCCtx->device->getDisplay(displayId);
544
545 if (display == nullptr) return -EINVAL;
546
547 ALOGD("ExynosHWCService::%s() displayID(%u) refreshRate(%u)", __func__, displayId, refreshRate);
548 if (display->mRefreshRateIndicatorHandler) {
549 display->mRefreshRateIndicatorHandler->updateRefreshRate(refreshRate);
550 }
551 return NO_ERROR;
552 }
553
554 } //namespace android
555