libdisplaymodule: resolve compilation errors
[GitHub/LineageOS/android_hardware_samsung_slsi_exynos7580.git] / libdisplaymodule / ExynosPrimaryDisplay.cpp
1 #include "ExynosPrimaryDisplay.h"
2 #include "ExynosHWCModule.h"
3 #include "ExynosHWCUtils.h"
4 #include "ExynosMPPModule.h"
5
6 #define DISPLAY_LOGD(msg, ...) ALOGD("[%s] " msg, mDisplayName.string(), ##__VA_ARGS__)
7 #define DISPLAY_LOGV(msg, ...) ALOGV("[%s] " msg, mDisplayName.string(), ##__VA_ARGS__)
8 #define DISPLAY_LOGI(msg, ...) ALOGI("[%s] " msg, mDisplayName.string(), ##__VA_ARGS__)
9 #define DISPLAY_LOGW(msg, ...) ALOGW("[%s] " msg, mDisplayName.string(), ##__VA_ARGS__)
10 #define DISPLAY_LOGE(msg, ...) ALOGE("[%s] " msg, mDisplayName.string(), ##__VA_ARGS__)
11
12 ExynosPrimaryDisplay::ExynosPrimaryDisplay(int numGSCs, struct exynos5_hwc_composer_device_1_t *pdev) :
13 ExynosOverlayDisplay(numGSCs, pdev)
14 {
15 }
16
17 ExynosPrimaryDisplay::~ExynosPrimaryDisplay()
18 {
19 }
20
21 int ExynosPrimaryDisplay::getDeconWinMap(int overlayIndex __unused, int totalOverlays __unused)
22 {
23 return 0;
24 }
25
26 void ExynosPrimaryDisplay::forceYuvLayersToFb(hwc_display_contents_1_t __unused *contents)
27 {
28 }
29
30 int ExynosPrimaryDisplay::getMPPForUHD(hwc_layer_1_t __unused &layer)
31 {
32 return 0;
33 }
34
35 int ExynosPrimaryDisplay::getRGBMPPIndex(int index)
36 {
37 return index;
38 }
39
40 bool ExynosPrimaryDisplay::isOverlaySupported(hwc_layer_1_t &layer, size_t index, bool useVPPOverlay __unused,
41 ExynosMPPModule** supportedInternalMPP, ExynosMPPModule** supportedExternalMPP)
42 {
43 // Exynos755555oesn't have any VPP Overlays
44 return ExynosDisplay::isOverlaySupported(layer, index, false, supportedInternalMPP, supportedExternalMPP);
45 }
46 bool ExynosPrimaryDisplay::isYuvDmaAvailable(int format, uint32_t dma)
47 {
48 return (format == HAL_PIXEL_FORMAT_EXYNOS_YCrCb_420_SP_M_FULL &&
49 dma == IDMA_G2);
50 }
51
52 void ExynosPrimaryDisplay::assignWindows(hwc_display_contents_1_t *contents)
53 {
54 // call the ExynosDisplay default implementation of assignWindows()
55 ExynosDisplay::assignWindows(contents);
56
57 // allocate the max bandwidth non-rgb layer to IDMA_G2
58 // consider only non-secure dma case - secure dma is already allocated to IDMA_G2
59
60 bool videoLayerFound = 0, curDmaYuvFound = 0, hasDRMlayer = 0;
61 uint32_t videoLayerIndex = 0, curDmaYuvIndex = 0;
62 uint32_t mTemp = 0, bandWidth = 0;
63 int fbLayerIndex = -1;
64
65 for (size_t i = 0; i < contents->numHwLayers; i++) {
66 hwc_layer_1_t &layer = contents->hwLayers[i];
67
68 if (!layer.handle)
69 continue;
70
71 private_handle_t *handle = private_handle_t::dynamicCast(layer.handle);
72
73 if (layer.compositionType == HWC_FRAMEBUFFER_TARGET)
74 fbLayerIndex = i;
75
76 // If there is DRM layer available, it has to go to IDMA_G2 channel.
77 if (layer.compositionType == HWC_OVERLAY &&
78 getDrmMode(handle->flags) == SECURE_DRM &&
79 !(layer.flags & HWC_SKIP_RENDERING)) {
80 hasDRMlayer = 1;
81 videoLayerFound = 1;
82 videoLayerIndex = i;
83 }
84
85 // If no DRM layer, find non-rgb overlay layer which can be supported by IDMA_G2.
86 if ((layer.compositionType == HWC_OVERLAY) &&
87 isYuvDmaAvailable(handle->format, IDMA_G2) &&
88 !(layer.flags & HWC_SKIP_RENDERING) &&
89 !hasDRMlayer) {
90
91 mTemp = (layer.sourceCropf.right - layer.sourceCropf.left) *
92 (layer.sourceCropf.bottom - layer.sourceCropf.top);
93 if (mTemp > bandWidth) {
94 bandWidth = mTemp;
95 videoLayerFound = 1;
96 videoLayerIndex = i;
97 }
98 }
99
100 if (((layer.compositionType == HWC_OVERLAY) ||
101 (layer.compositionType == HWC_FRAMEBUFFER_TARGET)) &&
102 (!curDmaYuvFound) &&
103 (mLayerInfos[i]->mDmaType == IDMA_G2)) {
104 curDmaYuvFound = 1;
105 curDmaYuvIndex = i;
106 }
107 }
108
109 if (curDmaYuvFound && videoLayerFound) {
110 mTemp = mLayerInfos[videoLayerIndex]->mDmaType;
111 mLayerInfos[videoLayerIndex]->mDmaType = mLayerInfos[curDmaYuvIndex]->mDmaType;
112 mLayerInfos[curDmaYuvIndex]->mDmaType = mTemp;
113 }
114
115 if (videoLayerFound && !curDmaYuvFound) {
116 if (prevfbTargetIdma == IDMA_G2) {
117 prevfbTargetIdma = (enum decon_idma_type) mLayerInfos[videoLayerIndex]->mDmaType;
118 mLayerInfos[videoLayerIndex]->mDmaType = IDMA_G2;
119 return;
120 }
121 mLayerInfos[videoLayerIndex]->mDmaType = IDMA_G2;
122 }
123
124 if (mFbNeeded && mFbWindow < NUM_HW_WINDOWS && fbLayerIndex >= 0)
125 prevfbTargetIdma = (enum decon_idma_type) mLayerInfos[fbLayerIndex]->mDmaType;
126 }
127
128 int ExynosPrimaryDisplay::postMPPM2M(hwc_layer_1_t &layer, struct decon_win_config *config, int win_map, int index)
129 {
130 int dst_format = mExternalMPPDstFormat;
131 private_handle_t *handle = private_handle_t::dynamicCast(layer.handle);
132 ExynosMPPModule *exynosMPP = mLayerInfos[index]->mExternalMPP;
133
134 if (exynosMPP == NULL) {
135 DISPLAY_LOGE("postMPPM2M is called but externMPP is NULL");
136 if (layer.acquireFenceFd >= 0)
137 close(layer.acquireFenceFd);
138 layer.acquireFenceFd = -1;
139 layer.releaseFenceFd = -1;
140 return -1;
141 }
142
143 hwc_frect_t sourceCrop = { 0, 0,
144 (float)WIDTH(layer.displayFrame), (float)HEIGHT(layer.displayFrame) };
145 int originalTransform = layer.transform;
146 hwc_rect_t originalDisplayFrame = layer.displayFrame;
147
148 /* OFF_Screen to ON_Screen changes */
149 if (getDrmMode(handle->flags) == SECURE_DRM)
150 recalculateDisplayFrame(layer, mXres, mYres);
151
152 if (mType != EXYNOS_VIRTUAL_DISPLAY &&
153 (isFormatRgb(handle->format) ||
154 (isYuvDmaAvailable(handle->format, mLayerInfos[index]->mDmaType) &&
155 WIDTH(layer.displayFrame) % getIDMAWidthAlign(handle->format) == 0 &&
156 HEIGHT(layer.displayFrame) % getIDMAHeightAlign(handle->format) == 0)))
157 dst_format = handle->format;
158
159 int err = exynosMPP->processM2M(layer, dst_format, &sourceCrop);
160
161 /* Restore displayFrame*/
162 layer.displayFrame = originalDisplayFrame;
163
164 if (err < 0) {
165 DISPLAY_LOGE("failed to configure MPP (type:%u, index:%u) for layer %u",
166 exynosMPP->mType, exynosMPP->mIndex, index);
167 return -1;
168 }
169
170 buffer_handle_t dst_buf = exynosMPP->mDstBuffers[exynosMPP->mCurrentBuf];
171 private_handle_t *dst_handle =
172 private_handle_t::dynamicCast(dst_buf);
173 int fence = exynosMPP->mDstConfig.releaseFenceFd;
174 hwc_frect originalCrop = layer.sourceCropf;
175
176 /* ExtMPP out is the input of Decon
177 * and Trsform was processed by ExtMPP
178 */
179 layer.sourceCropf = sourceCrop;
180 layer.transform = 0;
181 configureHandle(dst_handle, index, layer, fence, config[win_map]);
182
183 /* Restore sourceCropf and transform */
184 layer.sourceCropf = originalCrop;
185 layer.transform = originalTransform;
186 return 0;
187 }
188
189 void ExynosPrimaryDisplay::handleStaticLayers(hwc_display_contents_1_t *contents,
190 struct decon_win_config_data &win_data, int __unused tot_ovly_wins)
191 {
192 unsigned int bitmap = 0;
193 bool incorrect_mapping = false;
194
195 ExynosDisplay::handleStaticLayers(contents, win_data, tot_ovly_wins);
196
197 if (mLastFbWindow >= NUM_HW_WINDOWS) {
198 DISPLAY_LOGE("handleStaticLayers:: invalid mLastFbWindow(%d)", mLastFbWindow);
199 return;
200 }
201
202 win_data.config[mLastFbWindow].idma_type = prevfbTargetIdma;
203
204 for (size_t i = 0; i < NUM_HW_WINDOWS; i++) {
205 if (win_data.config[i].state == win_data.config[i].DECON_WIN_STATE_BUFFER) {
206 if (bitmap & (1 << win_data.config[i].idma_type)) {
207 ALOGE("handleStaticLayers: Channel-%d is mapped to multiple windows\n", win_data.config[i].idma_type);
208 incorrect_mapping = true;
209 }
210
211 bitmap |= 1 << win_data.config[i].idma_type;
212 }
213 }
214
215 if (incorrect_mapping) {
216 android::String8 result;
217 result.clear();
218 dump(result);
219 ALOGE("%s", result.string());
220 result.clear();
221 dumpLayerInfo(result);
222 ALOGE("%s", result.string());
223 ALOGE("Display Config:");
224 dump_win_config(&win_data.config[0]);
225 }
226 }
227
228 void ExynosPrimaryDisplay::dump_win_config(struct decon_win_config *config)
229 {
230 int win;
231 struct decon_win_config *cfg;
232 const char *state[] = { "DSBL", "COLR", "BUFF", "UPDT" };
233 const char *blending[] = { "NOBL", "PMUL", "COVR" };
234 const char *idma[] = { "G0", "G1", "V0", "V1", "VR0", "VR1", "G2" };
235
236 for (win = 0; win < MAX_DECON_WIN; win++) {
237 cfg = &config[win];
238
239 if (cfg->state == cfg->DECON_WIN_STATE_DISABLED)
240 continue;
241
242 if (cfg->state == cfg->DECON_WIN_STATE_COLOR) {
243 ALOGE("Win[%d]: %s, C(%d), Dst(%d,%d,%d,%d) "
244 "P(%d)\n",
245 win, state[cfg->state], cfg->color,
246 cfg->dst.x, cfg->dst.y,
247 cfg->dst.x + cfg->dst.w,
248 cfg->dst.y + cfg->dst.h,
249 cfg->protection);
250 } else {
251 ALOGE("Win[%d]: %s,(%d,%d,%d), F(%d) P(%d)"
252 " A(%d), %s, %s, fmt(%d) Src(%d,%d,%d,%d,f_w=%d,f_h=%d) ->"
253 " Dst(%d,%d,%d,%d,f_w=%d,f_h=%d) T(%d,%d,%d,%d)\n",
254 win, state[cfg->state], cfg->fd_idma[0],
255 cfg->fd_idma[1], cfg->fd_idma[2],
256 cfg->fence_fd, cfg->protection,
257 cfg->plane_alpha, blending[cfg->blending],
258 idma[cfg->idma_type], cfg->format,
259 cfg->src.x, cfg->src.y, cfg->src.x + cfg->src.w, cfg->src.y + cfg->src.h,
260 cfg->src.f_w, cfg->src.f_h,
261 cfg->dst.x, cfg->dst.y, cfg->dst.x + cfg->dst.w, cfg->dst.y + cfg->dst.h,
262 cfg->dst.f_w, cfg->dst.f_h,
263 cfg->transparent_area.x, cfg->transparent_area.y,
264 cfg->transparent_area.w, cfg->transparent_area.h);
265 }
266 }
267 }
268
269 int ExynosPrimaryDisplay::handleWindowUpdate(hwc_display_contents_1_t __unused *contents,
270 struct decon_win_config __unused *config)
271 {
272 int layerIdx = -1;
273 int updatedWinCnt = 0;
274 int totalWinCnt = 0;
275 int bitsPerPixel = 0;
276 size_t winUpdateInfoIdx;
277 hwc_rect updateRect = {this->mXres, this->mYres, 0, 0};
278 hwc_rect currentRect = {0, 0, 0, 0};
279 bool burstLengthCheckDone = false;
280 int alignAdjustment = 0;
281 int intersectionWidth = 0;
282
283 char value[PROPERTY_VALUE_MAX];
284 property_get("debug.hwc.winupdate", value, NULL);
285
286 if (!(!strcmp(value, "1") || !strcmp(value, "true")))
287 return -eWindowUpdateDisabled;
288
289 if (DECON_WIN_UPDATE_IDX < 0)
290 return -eWindowUpdateInvalidIndex;
291 winUpdateInfoIdx = DECON_WIN_UPDATE_IDX;
292
293 if (contents->flags & HWC_GEOMETRY_CHANGED)
294 return -eWindowUpdateGeometryChanged;
295
296 for (size_t i = 0; i < contents->numHwLayers; i++) {
297 if (contents->hwLayers[i].compositionType == HWC_FRAMEBUFFER)
298 continue;
299
300 if (!mFbNeeded && contents->hwLayers[i].compositionType == HWC_FRAMEBUFFER_TARGET)
301 continue;
302 int32_t windowIndex = mLayerInfos[i]->mWindowIndex;
303 if (config[windowIndex].state != config[windowIndex].DECON_WIN_STATE_DISABLED) {
304 totalWinCnt++;
305
306 if (winConfigChanged(&config[windowIndex], &this->mLastConfigData.config[windowIndex])) {
307 updatedWinCnt++;
308
309 currentRect.left = config[windowIndex].dst.x;
310 currentRect.right = config[windowIndex].dst.x + config[windowIndex].dst.w;
311 currentRect.top = config[windowIndex].dst.y;
312 currentRect.bottom = config[windowIndex].dst.y + config[windowIndex].dst.h;
313
314 if (hwcHasApiVersion((hwc_composer_device_1_t*)mHwc, HWC_DEVICE_API_VERSION_1_5))
315 {
316 private_handle_t *handle = NULL;
317 hwc_rect damageRect = {0, 0, 0, 0};
318 hwc_layer_1_t &layer = contents->hwLayers[i];
319 if (layer.handle)
320 handle = private_handle_t::dynamicCast(layer.handle);
321 getLayerRegion(layer, damageRect, eDamageRegion);
322
323 if (handle && !isScaled(layer) && !isRotated(layer)
324 && !(!(damageRect.left) && !(damageRect.top) && !(damageRect.right) && !(damageRect.bottom))) {
325 HLOGD("[WIN_UPDATE][surfaceDamage] layer w(%4d) h(%4d), dirty (%4d, %4d) - (%4d, %4d)",
326 handle->width, handle->height, damageRect.left, damageRect.top, damageRect.right, damageRect.bottom);
327
328 currentRect.left = config[windowIndex].dst.x - (int32_t)layer.sourceCropf.left + damageRect.left;
329 currentRect.right = config[windowIndex].dst.x - (int32_t)layer.sourceCropf.left + damageRect.right;
330 currentRect.top = config[windowIndex].dst.y - (int32_t)layer.sourceCropf.top + damageRect.top;
331 currentRect.bottom = config[windowIndex].dst.y - (int32_t)layer.sourceCropf.top + damageRect.bottom;
332
333 }
334 }
335
336 if ((currentRect.left > currentRect.right) || (currentRect.top > currentRect.bottom)) {
337 HLOGD("[WIN_UPDATE] window(%d) layer(%d) invalid region (%4d, %4d) - (%4d, %4d)",
338 i, layerIdx, currentRect.left, currentRect.top, currentRect.right, currentRect.bottom);
339 return -eWindowUpdateInvalidRegion;
340 }
341 HLOGD("[WIN_UPDATE] Updated Window(%d) Layer(%d) (%4d, %4d) - (%4d, %4d)",
342 windowIndex, i, currentRect.left, currentRect.top, currentRect.right, currentRect.bottom);
343 updateRect = expand(updateRect, currentRect);
344 }
345 }
346 }
347 if (updatedWinCnt == 0)
348 return -eWindowUpdateNotUpdated;
349
350 updateRect.left = ALIGN_DOWN(updateRect.left, WINUPDATE_X_ALIGNMENT);
351 updateRect.right = updateRect.left + ALIGN_UP(WIDTH(updateRect), WINUPDATE_W_ALIGNMENT);
352
353 if (HEIGHT(updateRect) < WINUPDATE_MIN_HEIGHT) {
354 if (updateRect.top + WINUPDATE_MIN_HEIGHT <= mYres)
355 updateRect.bottom = updateRect.top + WINUPDATE_MIN_HEIGHT;
356 else
357 updateRect.top = updateRect.bottom - WINUPDATE_MIN_HEIGHT;
358 }
359
360 if ((100 * (WIDTH(updateRect) * HEIGHT(updateRect)) / (this->mXres * this->mYres)) > WINUPDATE_THRESHOLD)
361 return -eWindowUpdateOverThreshold;
362
363 alignAdjustment = max(WINUPDATE_X_ALIGNMENT, WINUPDATE_W_ALIGNMENT);
364
365 while (1) {
366 burstLengthCheckDone = true;
367
368 for (size_t i = 0; i < contents->numHwLayers; i++) {
369 if (contents->hwLayers[i].compositionType == HWC_FRAMEBUFFER)
370 continue;
371 if (!mFbNeeded && contents->hwLayers[i].compositionType == HWC_FRAMEBUFFER_TARGET)
372 continue;
373 int32_t windowIndex = mLayerInfos[i]->mWindowIndex;
374 if (config[windowIndex].state != config[windowIndex].DECON_WIN_STATE_DISABLED) {
375 enum decon_pixel_format fmt = config[windowIndex].format;
376
377 if (fmt == DECON_PIXEL_FORMAT_RGBA_5551 || fmt == DECON_PIXEL_FORMAT_RGB_565 )
378 bitsPerPixel = 16;
379 else if (fmt == DECON_PIXEL_FORMAT_NV12 || fmt == DECON_PIXEL_FORMAT_NV21 ||
380 fmt == DECON_PIXEL_FORMAT_NV12M || fmt == DECON_PIXEL_FORMAT_NV21M)
381 bitsPerPixel = 12;
382 else
383 bitsPerPixel = 32;
384
385 currentRect.left = config[windowIndex].dst.x;
386 currentRect.right = config[windowIndex].dst.x + config[windowIndex].dst.w;
387 currentRect.top = config[windowIndex].dst.y;
388 currentRect.bottom = config[windowIndex].dst.y + config[windowIndex].dst.h;
389
390 intersectionWidth = WIDTH(intersection(currentRect, updateRect));
391
392 HLOGV("[WIN_UPDATE] win[%d] left(%d) right(%d) intersection(%d)", windowIndex, currentRect.left, currentRect.right, intersectionWidth);
393
394 if (intersectionWidth != 0 && (size_t)((intersectionWidth * bitsPerPixel) / 8) < BURSTLEN_BYTES) {
395 HLOGV("[WIN_UPDATE] win[%d] insufficient burst length ((%d)*(%d)/8) < %d", windowIndex, intersectionWidth, bitsPerPixel, BURSTLEN_BYTES);
396 burstLengthCheckDone = false;
397 break;
398 }
399 }
400 }
401
402 if (burstLengthCheckDone)
403 break;
404 HLOGD("[WIN_UPDATE] Adjusting update width. current left(%d) right(%d)", updateRect.left, updateRect.right);
405 if (updateRect.left >= alignAdjustment) {
406 updateRect.left -= alignAdjustment;
407 } else if (updateRect.right + alignAdjustment <= this->mXres) {
408 updateRect.right += alignAdjustment;
409 } else {
410 DISPLAY_LOGD("[WIN_UPDATE] Error during update width adjustment");
411 return -eWindowUpdateAdjustmentFail;
412 }
413 }
414
415 config[winUpdateInfoIdx].state = config[winUpdateInfoIdx].DECON_WIN_STATE_UPDATE;
416 config[winUpdateInfoIdx].dst.x = updateRect.left;
417 config[winUpdateInfoIdx].dst.y = updateRect.top;
418 config[winUpdateInfoIdx].dst.w = ALIGN_UP(WIDTH(updateRect), WINUPDATE_W_ALIGNMENT);
419 config[winUpdateInfoIdx].dst.h = HEIGHT(updateRect);
420
421 HLOGD("[WIN_UPDATE] UpdateRegion cfg (%4d, %4d) w(%4d) h(%4d) updatedWindowCnt(%d)",
422 config[winUpdateInfoIdx].dst.x, config[winUpdateInfoIdx].dst.y, config[winUpdateInfoIdx].dst.w, config[winUpdateInfoIdx].dst.h, updatedWinCnt);
423
424 /* Disable block mode if window update region is not full screen */
425 if ((config[winUpdateInfoIdx].dst.x != 0) || (config[winUpdateInfoIdx].dst.y != 0) ||
426 (config[winUpdateInfoIdx].dst.w != (uint32_t)mXres) || (config[winUpdateInfoIdx].dst.h != (uint32_t)mXres)) {
427 for (size_t i = 0; i < NUM_HW_WINDOWS; i++) {
428 memset(&config[i].transparent_area, 0, sizeof(config[i].transparent_area));
429 //memset(&config[i].covered_opaque_area, 0, sizeof(config[i].covered_opaque_area));
430 }
431 }
432
433 return 1;
434 }
435
436 int ExynosPrimaryDisplay::getIDMAWidthAlign(int format)
437 {
438 if (isFormatRgb(format))
439 return 1;
440 else
441 return 2;
442 }
443
444 int ExynosPrimaryDisplay::getIDMAHeightAlign(int format)
445 {
446 if (isFormatRgb(format))
447 return 1;
448 else
449 return 2;
450 }