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