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 
17 #include "ExynosDeviceInterface.h"
18 
19 #include <cutils/properties.h>
20 
21 #include <unordered_map>
22 #include <unordered_set>
23 
24 #include "ExynosDevice.h"
25 #include "ExynosHWCDebug.h"
26 #include "ExynosMPP.h"
27 #include "ExynosResourceManager.h"
28 #include "ExynosResourceRestriction.h"
29 
30 #ifndef USE_MODULE_ATTR
31 extern feature_support_t feature_table[];
32 #endif
33 
printDppRestriction(struct hwc_dpp_ch_restriction res)34 void ExynosDeviceInterface::printDppRestriction(struct hwc_dpp_ch_restriction res)
35 {
36     ALOGD("=========================================================");
37     ALOGD("id: %d", res.id);
38     ALOGD("hwc_dpp_restriction");
39     ALOGD("src_f_w (%d, %d, %d)", res.restriction.src_f_w.min, res.restriction.src_f_w.max, res.restriction.src_f_w.align);
40     ALOGD("src_f_h (%d, %d, %d)", res.restriction.src_f_h.min, res.restriction.src_f_h.max, res.restriction.src_f_h.align);
41     ALOGD("src_w (%d, %d, %d)", res.restriction.src_w.min, res.restriction.src_w.max, res.restriction.src_w.align);
42     ALOGD("src_h (%d, %d, %d)", res.restriction.src_h.min, res.restriction.src_h.max, res.restriction.src_h.align);
43     ALOGD("src_x_align(%d), src_y_align(%d)", res.restriction.src_x_align, res.restriction.src_y_align);
44 
45     ALOGD("dst_f_w (%d, %d, %d)", res.restriction.dst_f_w.min, res.restriction.dst_f_w.max, res.restriction.dst_f_w.align);
46     ALOGD("dst_f_h (%d, %d, %d)", res.restriction.dst_f_h.min, res.restriction.dst_f_h.max, res.restriction.dst_f_h.align);
47     ALOGD("dst_w (%d, %d, %d)", res.restriction.dst_w.min, res.restriction.dst_w.max, res.restriction.dst_w.align);
48     ALOGD("dst_h (%d, %d, %d)", res.restriction.dst_h.min, res.restriction.dst_h.max, res.restriction.dst_h.align);
49     ALOGD("dst_x_align(%d), dst_y_align(%d)", res.restriction.dst_x_align, res.restriction.dst_y_align);
50     ALOGD("src_h_rot_max(%d)", res.restriction.src_h_rot_max);
51 
52     ALOGD("blk_w (%d, %d, %d)", res.restriction.blk_w.min, res.restriction.blk_w.max, res.restriction.blk_w.align);
53     ALOGD("blk_h (%d, %d, %d)", res.restriction.blk_h.min, res.restriction.blk_h.max, res.restriction.blk_h.align);
54     ALOGD("blk_x_align(%d), blk_y_align(%d)", res.restriction.blk_x_align, res.restriction.blk_y_align);
55 
56     ALOGD("format cnt: %zu", res.restriction.formats.size());
57     for(int i = 0; i < res.restriction.formats.size(); i++) {
58         ALOGD("[%d] format: %d", i, res.restriction.formats[i]);
59     }
60 
61     ALOGD("scale down: %d, up: %d", res.restriction.scale_down, res.restriction.scale_up);
62     ALOGD("attr: 0x%lx", res.attr);
63 }
64 
makeDPURestrictions()65 int32_t ExynosDeviceInterface::makeDPURestrictions() {
66 #ifdef DISABLE_READ_RESTRICTIONS
67     return -EINVAL;
68 #endif
69     int32_t ret = 0;
70 
71     struct hwc_dpp_restrictions_info *dpuInfo = &mDPUInfo.dpuInfo;
72     HDEBUGLOGD(eDebugAttrSetting, "DPP ver : %d, cnt : %zu", dpuInfo->ver, dpuInfo->dpp_chs.size());
73     ExynosResourceManager *resourceManager = mExynosDevice->mResourceManager;
74 
75     /* format resctriction */
76     for (int i = 0; i < dpuInfo->dpp_chs.size(); i++){
77         hwc_dpp_restriction r = dpuInfo->dpp_chs[i].restriction;
78         HDEBUGLOGD(eDebugAttrSetting, "id : %d, format count : %zu", i, r.formats.size());
79     }
80 
81     /* Check attribute overlap */
82     std::unordered_set<unsigned long> attrs;
83     for (size_t i = 0; i < dpuInfo->dpp_chs.size(); ++i) {
84         const hwc_dpp_ch_restriction &r = dpuInfo->dpp_chs[i];
85         if (attrs.find(r.attr) != attrs.end())
86             mDPUInfo.overlap[i] = true;
87         else
88             attrs.insert(r.attr);
89         HDEBUGLOGD(eDebugAttrSetting, "Index : %zu, overlap %d", i, mDPUInfo.overlap[i]);
90     }
91 
92     for (int i = 0; i < dpuInfo->dpp_chs.size(); i++){
93         if (mDPUInfo.overlap[i]) continue;
94         hwc_dpp_restriction r = dpuInfo->dpp_chs[i].restriction;
95         mpp_phycal_type_t hwType = resourceManager->getPhysicalType(i);
96         for (auto &format: r.formats) {
97             restriction_key_t queried_format;
98             queried_format.hwType = hwType;
99             queried_format.nodeType = NODE_NONE;
100             /* format is HAL format */
101             queried_format.format = format;
102             queried_format.reserved = 0;
103             resourceManager->makeFormatRestrictions(queried_format);
104             HDEBUGLOGD(eDebugAttrSetting, "%s : %d", getMPPStr(hwType).string(), format);
105         }
106     }
107 
108     for (int i = 0; i < dpuInfo->dpp_chs.size(); i++){
109         if (mDPUInfo.overlap[i]) continue;
110         const hwc_dpp_restriction &r = dpuInfo->dpp_chs[i].restriction;
111 
112         /* RGB size restrictions */
113         restriction_size rSize;
114         rSize.maxDownScale = r.scale_down;
115         rSize.maxUpScale = r.scale_up;
116         rSize.maxFullWidth = r.dst_f_w.max;
117         rSize.maxFullHeight = r.dst_f_h.max;
118         rSize.minFullWidth = r.dst_f_w.min;
119         rSize.minFullHeight = r.dst_f_h.min;;
120         rSize.fullWidthAlign = r.dst_x_align;
121         rSize.fullHeightAlign = r.dst_y_align;;
122         rSize.maxCropWidth = r.src_w.max;
123         rSize.maxCropHeight = r.src_h.max;
124         rSize.minCropWidth = r.src_w.min;
125         rSize.minCropHeight = r.src_h.min;
126         rSize.cropXAlign = r.src_x_align;
127         rSize.cropYAlign = r.src_y_align;
128         rSize.cropWidthAlign = r.blk_x_align;
129         rSize.cropHeightAlign = r.blk_y_align;
130 
131         mpp_phycal_type_t hwType = resourceManager->getPhysicalType(i);
132         if (hwType <= MPP_DPP_NUM) {
133             auto newMaxDownscale =
134                     static_cast<unsigned int>(property_get_int32("vendor.hwc.dpp.downscale", 0));
135             if (newMaxDownscale != 0) {
136                 rSize.maxDownScale = min(rSize.maxDownScale, newMaxDownscale);
137                 ALOGI("%s:: Apply DPP downscale restriction on 1/%d", __func__, rSize.maxDownScale);
138             }
139         }
140         resourceManager->makeSizeRestrictions(hwType, rSize, RESTRICTION_RGB);
141 
142         /* YUV size restrictions */
143         rSize.minCropWidth = 32; //r.src_w.min;
144         rSize.minCropHeight = 32; //r.src_h.min;
145         rSize.fullWidthAlign = max(r.dst_x_align, YUV_CHROMA_H_SUBSAMPLE);
146         rSize.fullHeightAlign = max(r.dst_y_align, YUV_CHROMA_V_SUBSAMPLE);
147         rSize.cropXAlign = max(r.src_x_align, YUV_CHROMA_H_SUBSAMPLE);
148         rSize.cropYAlign = max(r.src_y_align, YUV_CHROMA_V_SUBSAMPLE);
149         rSize.cropWidthAlign = max(r.blk_x_align, YUV_CHROMA_H_SUBSAMPLE);
150         rSize.cropHeightAlign = max(r.blk_y_align, YUV_CHROMA_V_SUBSAMPLE);
151 
152         resourceManager->makeSizeRestrictions(hwType, rSize, RESTRICTION_YUV);
153     }
154 
155     for (auto it: resourceManager->getOtfMPPs()) {
156         if (mDPUInfo.dpuInfo.ppc)
157             it->setPPC(static_cast<float>(mDPUInfo.dpuInfo.ppc));
158         if (mDPUInfo.dpuInfo.max_disp_freq)
159             it->setClockKhz(mDPUInfo.dpuInfo.max_disp_freq);
160     }
161 
162     return ret;
163 }
164 
updateFeatureTable()165 int32_t ExynosDeviceInterface::updateFeatureTable() {
166     const struct hwc_dpp_restrictions_info &dpuInfo = mDPUInfo.dpuInfo;
167     if (mExynosDevice->mResourceManager == NULL)
168         return -1;
169 
170     const ExynosResourceManager &resourceManager = *(mExynosDevice->mResourceManager);
171     const uint32_t featureTableCnt = resourceManager.getFeatureTableSize();
172 
173     const int attrMapCnt = sizeof(dpu_attr_map_table)/sizeof(dpu_attr_map_t);
174     const int dpp_cnt = dpuInfo.dpp_chs.size();
175 
176     HDEBUGLOGD(eDebugAttrSetting, "Before");
177     for (uint32_t j = 0; j < featureTableCnt; j++){
178         HDEBUGLOGD(eDebugAttrSetting, "type : %d, feature : 0x%lx",
179                 feature_table[j].hwType,
180                 (unsigned long)feature_table[j].attr);
181     }
182 
183     // dpp count
184     for (int i = 0; i < dpp_cnt; i++){
185         hwc_dpp_ch_restriction c_r = dpuInfo.dpp_chs[i];
186         if (mDPUInfo.overlap[i]) continue;
187         HDEBUGLOGD(eDebugAttrSetting, "DPU attr : (ch:%d), 0x%lx", i, (unsigned long)c_r.attr);
188         mpp_phycal_type_t hwType = resourceManager.getPhysicalType(i);
189         // feature table count
190         for (uint32_t j = 0; j < featureTableCnt; j++){
191             if (feature_table[j].hwType == hwType) {
192                 uint64_t attr = 0;
193                 // dpp attr count
194                 for (int k = 0; k < attrMapCnt; k++) {
195                     if (c_r.attr & (1 << dpu_attr_map_table[k].dpp_attr)) {
196                         attr |= dpu_attr_map_table[k].hwc_attr;
197                     }
198                 }
199                 auto it = sw_feature_table.find(hwType);
200                 if (it != sw_feature_table.end())
201                     attr |= it->second;
202                 feature_table[j].attr = attr;
203             }
204         }
205     }
206 
207     HDEBUGLOGD(eDebugAttrSetting, "After");
208     for (uint32_t j = 0; j < featureTableCnt; j++){
209         HDEBUGLOGD(eDebugAttrSetting, "type : %d, feature : 0x%lx",
210                 feature_table[j].hwType,
211                 (unsigned long)feature_table[j].attr);
212         mExynosDevice->mResourceManager->mMPPAttrs.insert(std::make_pair((uint32_t)feature_table[j].hwType,
213                     (uint64_t)feature_table[j].attr));
214     }
215     return 0;
216 }
217 
218