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