1 /*
2  * Copyright (C) 2019 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 //#define LOG_NDEBUG 0
17 #include "ExynosExternalDisplayModule.h"
18 #include "ExynosPrimaryDisplayModule.h"
19 
20 #ifdef USES_VIRTUAL_DISPLAY
21 #include "ExynosVirtualDisplayModule.h"
22 #endif
23 
24 #include "ExynosDisplayDrmInterfaceModule.h"
25 #include "ExynosHWCDebug.h"
26 #include "ExynosHWCHelper.h"
27 
28 #define SKIP_FRAME_COUNT        3
29 
30 using namespace gs101;
31 
ExynosExternalDisplayModule(uint32_t index,ExynosDevice * device,const std::string & displayName)32 ExynosExternalDisplayModule::ExynosExternalDisplayModule(uint32_t index, ExynosDevice* device,
33                                                          const std::string& displayName)
34       : ExynosExternalDisplay(index, device, displayName) {
35     mColorManager = std::make_unique<ColorManager>(this, static_cast<ExynosDeviceModule*>(device));
36 }
37 
~ExynosExternalDisplayModule()38 ExynosExternalDisplayModule::~ExynosExternalDisplayModule ()
39 {
40 
41 }
42 
validateWinConfigData()43 int32_t ExynosExternalDisplayModule::validateWinConfigData()
44 {
45     bool flagValidConfig = true;
46 
47     if (ExynosDisplay::validateWinConfigData() != NO_ERROR)
48         flagValidConfig = false;
49 
50     for (size_t i = 0; i < mDpuData.configs.size(); i++) {
51         struct exynos_win_config_data &config = mDpuData.configs[i];
52         if (config.state == config.WIN_STATE_BUFFER) {
53             bool configInvalid = false;
54             uint32_t mppType = config.assignedMPP->mPhysicalType;
55             if ((config.src.w != config.dst.w) ||
56                 (config.src.h != config.dst.h)) {
57                 if ((mppType == MPP_DPP_GF) ||
58                     (mppType == MPP_DPP_VG) ||
59                     (mppType == MPP_DPP_VGF)) {
60                     DISPLAY_LOGE("WIN_CONFIG error: invalid assign id : %zu,  s_w : %d, d_w : %d, s_h : %d, d_h : %d, mppType : %d",
61                             i, config.src.w, config.dst.w, config.src.h, config.dst.h, mppType);
62                     configInvalid = true;
63                 }
64             }
65             if (configInvalid) {
66                 config.state = config.WIN_STATE_DISABLED;
67                 flagValidConfig = false;
68             }
69         }
70     }
71     if (flagValidConfig)
72         return NO_ERROR;
73     else
74         return -EINVAL;
75 }
76 
getColorModes(uint32_t * outNumModes,int32_t * outModes)77 int32_t ExynosExternalDisplayModule::getColorModes(uint32_t* outNumModes, int32_t* outModes) {
78     return mColorManager->getColorModes(outNumModes, outModes);
79 }
80 
setColorMode(int32_t mode)81 int32_t ExynosExternalDisplayModule::setColorMode(int32_t mode) {
82     return mColorManager->setColorMode(mode);
83 }
84 
getRenderIntents(int32_t mode,uint32_t * outNumIntents,int32_t * outIntents)85 int32_t ExynosExternalDisplayModule::getRenderIntents(int32_t mode, uint32_t* outNumIntents,
86                                                       int32_t* outIntents) {
87     return mColorManager->getRenderIntents(mode, outNumIntents, outIntents);
88 }
89 
setColorModeWithRenderIntent(int32_t mode,int32_t intent)90 int32_t ExynosExternalDisplayModule::setColorModeWithRenderIntent(int32_t mode, int32_t intent) {
91     return mColorManager->setColorModeWithRenderIntent(mode, intent);
92 }
93 
setColorTransform(const float * matrix,int32_t hint)94 int32_t ExynosExternalDisplayModule::setColorTransform(const float* matrix, int32_t hint) {
95     return mColorManager->setColorTransform(matrix, hint);
96 }
97 
updateColorConversionInfo()98 int32_t ExynosExternalDisplayModule::updateColorConversionInfo() {
99     return mColorManager->updateColorConversionInfo();
100 }
101 
resetColorMappingInfo(ExynosMPPSource * mppSrc)102 int32_t ExynosExternalDisplayModule::resetColorMappingInfo(ExynosMPPSource* mppSrc) {
103     return mColorManager->resetColorMappingInfo(mppSrc);
104 }
105 
deliverWinConfigData()106 int ExynosExternalDisplayModule::deliverWinConfigData() {
107     int ret = 0;
108     ExynosDisplayDrmInterfaceModule* moduleDisplayInterface =
109             (ExynosDisplayDrmInterfaceModule*)(mDisplayInterface.get());
110     GsInterfaceType* displayColorInterface = getDisplayColorInterface();
111 
112     bool forceDisplayColorSetting = false;
113     if (!getDisplaySceneInfo().displaySettingDelivered || isForceColorUpdate())
114         forceDisplayColorSetting = true;
115 
116     setForceColorUpdate(false);
117 
118     if (displayColorInterface != nullptr) {
119         moduleDisplayInterface
120                 ->setColorSettingChanged(getDisplaySceneInfo().needDisplayColorSetting(),
121                                          forceDisplayColorSetting);
122     }
123 
124     ret = ExynosDisplay::deliverWinConfigData();
125 
126     if (mDpuData.enable_readback && !mDpuData.readback_info.requested_from_service)
127         getDisplaySceneInfo().displaySettingDelivered = false;
128     else
129         getDisplaySceneInfo().displaySettingDelivered = true;
130 
131     return ret;
132 }
133 
invalidate()134 void ExynosExternalDisplayModule::invalidate() {
135     ExynosExternalDisplay::invalidate();
136 
137     // invalidate() is invoked when we handle hotplug event for the external display.
138     // we need to call clear() here to ensure both layerDataMappingInfo and
139     // prev_layerDataMappingInfo are clearead in DisplaySceneInfo, otherwise old
140     // mappings preserved in prev_layerDataMappingInfo will be re-used after the
141     // next hotplug, causing color issues (see b/325549729).
142     getDisplaySceneInfo().clear();
143 }
144