ea2a6eac1d8a8a2322085abdd28551bf054db208
[GitHub/LineageOS/android_hardware_samsung_slsi_exynos.git] / libvppdisplay / ExynosDisplay.cpp
1 #define ATRACE_TAG ATRACE_TAG_GRAPHICS
2
3 //#define LOG_NDEBUG 0
4 #define LOG_TAG "display"
5 #include "ExynosDisplay.h"
6 #include "ExynosHWCUtils.h"
7 #include "ExynosMPPModule.h"
8 #include "ExynosHWCDebug.h"
9 #include <utils/misc.h>
10 #include <utils/Trace.h>
11 #include <inttypes.h>
12 #if defined(USES_DUAL_DISPLAY)
13 #include "ExynosSecondaryDisplayModule.h"
14 #endif
15
16 int getGCD(int a, int b)
17 {
18 if (b == 0)
19 return a;
20 else
21 return getGCD(b, a%b);
22 }
23
24 int getLCM(int a, int b)
25 {
26 return (a*b)/getGCD(a,b);
27 }
28
29 bool frameChanged(decon_frame *f1, decon_frame *f2)
30 {
31 return f1->x != f2->x ||
32 f1->y != f2->y ||
33 f1->w != f2->w ||
34 f1->h != f2->h ||
35 f1->f_w != f2->f_w ||
36 f1->f_h != f2->f_h;
37 }
38
39 bool winConfigChanged(decon_win_config *c1, decon_win_config *c2)
40 {
41 return c1->state != c2->state ||
42 c1->fd_idma[0] != c2->fd_idma[0] ||
43 c1->fd_idma[1] != c2->fd_idma[1] ||
44 c1->fd_idma[2] != c2->fd_idma[2] ||
45 frameChanged(&c1->src, &c2->src) ||
46 frameChanged(&c1->dst, &c2->dst) ||
47 c1->format != c2->format ||
48 c1->blending != c2->blending ||
49 c1->plane_alpha != c2->plane_alpha;
50 }
51
52 void ExynosDisplay::dumpConfig(decon_win_config &c)
53 {
54 DISPLAY_LOGD(eDebugWinConfig, "\tstate = %u", c.state);
55 if (c.state == c.DECON_WIN_STATE_COLOR) {
56 DISPLAY_LOGD(eDebugWinConfig, "\t\tcolor = %u", c.color);
57 } else if (c.state != c.DECON_WIN_STATE_DISABLED) {
58 DISPLAY_LOGD(eDebugWinConfig, "\t\tfd = %d, dma = %u "
59 "src_f_w = %u, src_f_h = %u, src_x = %d, src_y = %d, src_w = %u, src_h = %u, "
60 "dst_f_w = %u, dst_f_h = %u, dst_x = %d, dst_y = %d, dst_w = %u, dst_h = %u, "
61 "format = %u, blending = %u, protection = %u, transparent(x:%d, y:%d, w:%d, h:%d)",
62 c.fd_idma[0], c.idma_type,
63 c.src.f_w, c.src.f_h, c.src.x, c.src.y, c.src.w, c.src.h,
64 c.dst.f_w, c.dst.f_h, c.dst.x, c.dst.y, c.dst.w, c.dst.h,
65 c.format, c.blending, c.protection,
66 c.transparent_area.x, c.transparent_area.y, c.transparent_area.w, c.transparent_area.h);
67 }
68 }
69
70 void ExynosDisplay::dumpConfig(decon_win_config &c, android::String8& result)
71 {
72 result.appendFormat("\tstate = %u", c.state);
73 if (c.state == c.DECON_WIN_STATE_COLOR) {
74 result.appendFormat("\t\tcolor = %u", c.color);
75 } else {
76 result.appendFormat("\t\tfd = %d, dma = %u "
77 "src_f_w = %u, src_f_h = %u, src_x = %d, src_y = %d, src_w = %u, src_h = %u, "
78 "dst_f_w = %u, dst_f_h = %u, dst_x = %d, dst_y = %d, dst_w = %u, dst_h = %u, "
79 "format = %u, blending = %u, protection = %u, transparent(x:%d, y:%d, w:%d, h:%d)",
80 c.fd_idma[0], c.idma_type,
81 c.src.f_w, c.src.f_h, c.src.x, c.src.y, c.src.w, c.src.h,
82 c.dst.f_w, c.dst.f_h, c.dst.x, c.dst.y, c.dst.w, c.dst.h,
83 c.format, c.blending, c.protection,
84 c.transparent_area.x, c.transparent_area.y, c.transparent_area.w, c.transparent_area.h);
85 }
86 }
87
88 enum decon_pixel_format halFormatToS3CFormat(int format)
89 {
90 switch (format) {
91 case HAL_PIXEL_FORMAT_RGBA_8888:
92 return DECON_PIXEL_FORMAT_RGBA_8888;
93 case HAL_PIXEL_FORMAT_RGBX_8888:
94 return DECON_PIXEL_FORMAT_RGBX_8888;
95 case HAL_PIXEL_FORMAT_RGB_565:
96 return DECON_PIXEL_FORMAT_RGB_565;
97 case HAL_PIXEL_FORMAT_BGRA_8888:
98 return DECON_PIXEL_FORMAT_BGRA_8888;
99 #ifdef EXYNOS_SUPPORT_BGRX_8888
100 case HAL_PIXEL_FORMAT_BGRX_8888:
101 return DECON_PIXEL_FORMAT_BGRX_8888;
102 #endif
103 case HAL_PIXEL_FORMAT_EXYNOS_YV12_M:
104 return DECON_PIXEL_FORMAT_YVU420M;
105 case HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_P_M:
106 return DECON_PIXEL_FORMAT_YUV420M;
107 case HAL_PIXEL_FORMAT_EXYNOS_YCrCb_420_SP_M:
108 case HAL_PIXEL_FORMAT_EXYNOS_YCrCb_420_SP_M_FULL:
109 return DECON_PIXEL_FORMAT_NV21M;
110 case HAL_PIXEL_FORMAT_YCrCb_420_SP:
111 return DECON_PIXEL_FORMAT_NV21;
112 case HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SP_M:
113 case HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SP_M_PRIV:
114 case HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SP_M_S10B:
115 return DECON_PIXEL_FORMAT_NV12M;
116 #ifdef DECON_PIXEL_FORMAT_NV12N_10B
117 case HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SPN_S10B:
118 return DECON_PIXEL_FORMAT_NV12N_10B;
119 #endif
120 #ifdef DECON_PIXEL_FORMAT_NV12N
121 case HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SPN:
122 return DECON_PIXEL_FORMAT_NV12N;
123 #endif
124 default:
125 return DECON_PIXEL_FORMAT_MAX;
126 }
127 }
128
129 int S3CFormatToHalFormat(enum decon_pixel_format format)
130 {
131 switch (format) {
132 case DECON_PIXEL_FORMAT_RGBA_8888:
133 return HAL_PIXEL_FORMAT_RGBA_8888;
134 case DECON_PIXEL_FORMAT_RGBX_8888:
135 return HAL_PIXEL_FORMAT_RGBX_8888;
136 case DECON_PIXEL_FORMAT_RGB_565:
137 return HAL_PIXEL_FORMAT_RGB_565;
138 case DECON_PIXEL_FORMAT_BGRA_8888:
139 return HAL_PIXEL_FORMAT_BGRA_8888;
140 #ifdef EXYNOS_SUPPORT_BGRX_8888
141 case DECON_PIXEL_FORMAT_BGRX_8888:
142 return HAL_PIXEL_FORMAT_BGRX_8888;
143 #endif
144 case DECON_PIXEL_FORMAT_YVU420M:
145 return HAL_PIXEL_FORMAT_EXYNOS_YV12_M;
146 case DECON_PIXEL_FORMAT_YUV420M:
147 return HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_P_M;
148 /* HAL_PIXEL_FORMAT_EXYNOS_YCrCb_420_SP_M_FULL ?? */
149 case DECON_PIXEL_FORMAT_NV21M:
150 return HAL_PIXEL_FORMAT_EXYNOS_YCrCb_420_SP_M;
151 case DECON_PIXEL_FORMAT_NV21:
152 return HAL_PIXEL_FORMAT_YCrCb_420_SP;
153 /* HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SP_M_PRIV, HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SP_M_S10B */
154 case DECON_PIXEL_FORMAT_NV12M:
155 return HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SP_M;
156 #ifdef DECON_PIXEL_FORMAT_NV12N
157 case DECON_PIXEL_FORMAT_NV12N:
158 return HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SPN;
159 #endif
160 #ifdef DECON_PIXEL_FORMAT_NV12N_10B
161 case DECON_PIXEL_FORMAT_NV12N_10B:
162 return HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SPN_S10B;
163 #endif
164 default:
165 return -1;
166 }
167 }
168
169 bool isFormatSupported(int format)
170 {
171 return halFormatToS3CFormat(format) < DECON_PIXEL_FORMAT_MAX;
172 }
173
174 enum decon_blending halBlendingToS3CBlending(int32_t blending)
175 {
176 switch (blending) {
177 case HWC_BLENDING_NONE:
178 return DECON_BLENDING_NONE;
179 case HWC_BLENDING_PREMULT:
180 return DECON_BLENDING_PREMULT;
181 case HWC_BLENDING_COVERAGE:
182 return DECON_BLENDING_COVERAGE;
183
184 default:
185 return DECON_BLENDING_MAX;
186 }
187 }
188
189 bool isBlendingSupported(int32_t blending)
190 {
191 return halBlendingToS3CBlending(blending) < DECON_BLENDING_MAX;
192 }
193
194 #define NUMA(a) (sizeof(a) / sizeof(a [0]))
195 const char *deconFormat2str(uint32_t format)
196 {
197 android::String8 result;
198
199 for (unsigned int n1 = 0; n1 < NUMA(deconFormat); n1++) {
200 if (format == deconFormat[n1].format) {
201 return deconFormat[n1].desc;
202 }
203 }
204
205 result.appendFormat("? %08x", format);
206 return result;
207 }
208
209 enum vpp_rotate halTransformToHWRot(uint32_t halTransform)
210 {
211 switch (halTransform) {
212 case HAL_TRANSFORM_FLIP_H:
213 return VPP_ROT_YFLIP;
214 case HAL_TRANSFORM_FLIP_V:
215 return VPP_ROT_XFLIP;
216 case HAL_TRANSFORM_ROT_180:
217 return VPP_ROT_180;
218 case HAL_TRANSFORM_ROT_90:
219 return VPP_ROT_90;
220 case (HAL_TRANSFORM_ROT_90|HAL_TRANSFORM_FLIP_H):
221 /*
222 * HAL: HAL_TRANSFORM_FLIP_H -> HAL_TRANSFORM_ROT_90
223 * VPP: ROT_90 -> XFLIP
224 */
225 return VPP_ROT_90_XFLIP;
226 case (HAL_TRANSFORM_ROT_90|HAL_TRANSFORM_FLIP_V):
227 /*
228 * HAL: HAL_TRANSFORM_FLIP_V -> HAL_TRANSFORM_ROT_90
229 * VPP: ROT_90 -> YFLIP
230 */
231 return VPP_ROT_90_YFLIP;
232 case HAL_TRANSFORM_ROT_270:
233 return VPP_ROT_270;
234 default:
235 return VPP_ROT_NORMAL;
236 }
237 }
238
239 ExynosDisplay::ExynosDisplay(int __unused numGSCs)
240 : mDisplayFd(-1),
241 mType(0),
242 mPanelType(PANEL_LEGACY),
243 mDSCHSliceNum(WINUPDATE_DSC_H_SLICE_NUM),
244 mDSCYSliceSize(WINUPDATE_DSC_Y_SLICE_SIZE),
245 mXres(0),
246 mYres(0),
247 mXdpi(0),
248 mYdpi(0),
249 mVsyncPeriod(0),
250 mBlanked(true),
251 mHwc(NULL),
252 mAllocDevice(NULL),
253 mGrallocModule(NULL),
254 mLastFbWindow(NO_FB_NEEDED),
255 mVirtualOverlayFlag(0),
256 mBypassSkipStaticLayer(false),
257 mMPPLayers(0),
258 mYuvLayers(0),
259 mHasDrmSurface(false),
260 mFbNeeded(false),
261 mFirstFb(0),
262 mLastFb(0),
263 mFbWindow(0),
264 mForceFb(false),
265 mForceOverlayLayerIndex(-1),
266 mAllowedOverlays(5),
267 mOtfMode(OTF_OFF),
268 mGscUsed(false),
269 mMaxWindowOverlapCnt(NUM_HW_WINDOWS),
270 mUseSecureDMA(false),
271 mExternalMPPDstFormat(HAL_PIXEL_FORMAT_RGBX_8888),
272 mSkipStaticInitFlag(false),
273 mNumStaticLayers(0),
274 mLastRetireFenceFd(-1),
275 mFbPreAssigned(false),
276 mActiveConfigIndex(0),
277 mWinData(NULL)
278 {
279 memset(mLastMPPMap, 0, sizeof(mLastMPPMap));
280 memset(mLastHandles, 0, sizeof(mLastHandles));
281 memset(&mLastConfigData, 0, sizeof(mLastConfigData));
282 memset(mLastLayerHandles, 0, sizeof(mLastLayerHandles));
283 memset(&mFbUpdateRegion, 0, sizeof(mFbUpdateRegion));
284
285 mPreProcessedInfo.mHasDrmSurface = false;
286 mCheckIntMPP = new ExynosMPPModule(NULL, MPP_VGR, 0);
287
288 mWinData = (struct decon_win_config_data *)malloc(sizeof(*mWinData));
289 if (mWinData == NULL)
290 DISPLAY_LOGE("Fail to allocate mWinData");
291 }
292 ExynosDisplay::ExynosDisplay(uint32_t type, struct exynos5_hwc_composer_device_1_t *pdev)
293 : mDisplayFd(-1),
294 mType(type),
295 mPanelType(PANEL_LEGACY),
296 mDSCHSliceNum(WINUPDATE_DSC_H_SLICE_NUM),
297 mDSCYSliceSize(WINUPDATE_DSC_Y_SLICE_SIZE),
298 mXres(0),
299 mYres(0),
300 mXdpi(0),
301 mYdpi(0),
302 mVsyncPeriod(0),
303 mBlanked(true),
304 mHwc(pdev),
305 mAllocDevice(NULL),
306 mGrallocModule(NULL),
307 mLastFbWindow(NO_FB_NEEDED),
308 mVirtualOverlayFlag(0),
309 mBypassSkipStaticLayer(false),
310 mMPPLayers(0),
311 mYuvLayers(0),
312 mHasDrmSurface(false),
313 mFbNeeded(false),
314 mFirstFb(0),
315 mLastFb(0),
316 mFbWindow(0),
317 mForceFb(false),
318 mForceOverlayLayerIndex(-1),
319 mAllowedOverlays(5),
320 mOtfMode(OTF_OFF),
321 mGscUsed(false),
322 mMaxWindowOverlapCnt(NUM_HW_WINDOWS),
323 mUseSecureDMA(false),
324 mExternalMPPDstFormat(HAL_PIXEL_FORMAT_RGBX_8888),
325 mSkipStaticInitFlag(false),
326 mNumStaticLayers(0),
327 mLastRetireFenceFd(-1),
328 mFbPreAssigned(false),
329 mActiveConfigIndex(0),
330 mWinData(NULL)
331 {
332 memset(mLastMPPMap, 0, sizeof(mLastMPPMap));
333 memset(mLastHandles, 0, sizeof(mLastHandles));
334 memset(&mLastConfigData, 0, sizeof(mLastConfigData));
335 memset(mLastLayerHandles, 0, sizeof(mLastLayerHandles));
336
337 switch (mType) {
338 case EXYNOS_VIRTUAL_DISPLAY:
339 mDisplayName = android::String8("VirtualDisplay");
340 break;
341 case EXYNOS_EXTERNAL_DISPLAY:
342 mDisplayName = android::String8("ExternalDisplay");
343 break;
344 case EXYNOS_PRIMARY_DISPLAY:
345 mDisplayName = android::String8("PrimaryDisplay");
346 break;
347 #if defined(USES_DUAL_DISPLAY)
348 case EXYNOS_SECONDARY_DISPLAY:
349 mDisplayName = android::String8("SecondaryDisplay");
350 break;
351 #endif
352 default:
353 mDisplayName = android::String8("Unknown");
354 break;
355 }
356 memset(&mFbUpdateRegion, 0, sizeof(mFbUpdateRegion));
357
358 mPreProcessedInfo.mHasDrmSurface = false;
359 mCheckIntMPP = new ExynosMPPModule(NULL, MPP_VGR, 0);
360
361 mWinData = (struct decon_win_config_data *)malloc(sizeof(*mWinData));
362 if (mWinData == NULL)
363 DISPLAY_LOGE("Fail to allocate mWinData");
364 }
365
366 ExynosDisplay::~ExynosDisplay()
367 {
368 if (!mLayerInfos.isEmpty()) {
369 for (size_t i = 0; i < mLayerInfos.size(); i++) {
370 delete mLayerInfos[i];
371 }
372 mLayerInfos.clear();
373 }
374 if (mCheckIntMPP != NULL) {
375 delete mCheckIntMPP;
376 mCheckIntMPP = NULL;
377 }
378
379 if (mWinData != NULL)
380 free(mWinData);
381 }
382
383 int ExynosDisplay::prepare(hwc_display_contents_1_t *contents)
384 {
385 ATRACE_CALL();
386 DISPLAY_LOGD(eDebugDefault, "preparing %u layers for FIMD", contents->numHwLayers);
387
388 if (!mForceFb)
389 skipStaticLayers(contents);
390
391 if (mVirtualOverlayFlag)
392 mFbNeeded = 0;
393
394 if (!mFbNeeded)
395 mFbWindow = NO_FB_NEEDED;
396
397 return 0;
398 }
399
400 int ExynosDisplay::set(hwc_display_contents_1_t *contents)
401 {
402 hwc_layer_1_t *fb_layer = NULL;
403 int err = 0;
404
405 if (mFbWindow != NO_FB_NEEDED) {
406 if (contents->numHwLayers >= 1 &&
407 contents->hwLayers[contents->numHwLayers - 1].compositionType == HWC_FRAMEBUFFER_TARGET)
408 fb_layer = &contents->hwLayers[contents->numHwLayers - 1];
409
410 if (CC_UNLIKELY(!fb_layer)) {
411 DISPLAY_LOGE("framebuffer target expected, but not provided");
412 err = -EINVAL;
413 } else {
414 DISPLAY_LOGD(eDebugDefault, "framebuffer target buffer:");
415 dumpLayer(eDebugDefault, fb_layer);
416 }
417 }
418
419 int fence;
420 if (!err) {
421 fence = postFrame(contents);
422 if (fence < 0)
423 err = fence;
424 }
425
426 #if defined(USES_DUAL_DISPLAY)
427 if (mType != EXYNOS_SECONDARY_DISPLAY)
428 {
429 #endif
430 if (err)
431 fence = clearDisplay();
432
433 if (fence == 0) {
434 /*
435 * WIN_CONFIG is skipped, not error
436 */
437 fence = -1;
438 if (mLastRetireFenceFd >= 0) {
439 int dup_fd = dup(mLastRetireFenceFd);
440 if (dup_fd >= 0) {
441 fence = dup_fd;
442 mLastRetireFenceFd = dup_fd;
443 dupFence(fence, contents);
444 } else {
445 DISPLAY_LOGW("mLastRetireFenceFd dup failed: %s", strerror(errno));
446 mLastRetireFenceFd = -1;
447 }
448 } else {
449 ALOGE("WIN_CONFIG is skipped, but mLastRetireFenceFd is not valid");
450 }
451 } else {
452 mLastRetireFenceFd = fence;
453 dupFence(fence, contents);
454 }
455 #if defined(USES_DUAL_DISPLAY)
456 }
457 #endif
458
459 return err;
460 }
461
462 void ExynosDisplay::dupFence(int fence, hwc_display_contents_1_t *contents)
463 {
464 if (contents == NULL)
465 return;
466
467 for (size_t i = 0; i < contents->numHwLayers; i++) {
468 hwc_layer_1_t &layer = contents->hwLayers[i];
469 private_handle_t *handle = NULL;
470 if (layer.handle != NULL)
471 handle = private_handle_t::dynamicCast(layer.handle);
472
473 if ((mVirtualOverlayFlag == true) && (layer.compositionType == HWC_OVERLAY) &&
474 ((handle != NULL) && (getDrmMode(handle->flags) == NO_DRM)) &&
475 (mFirstFb <= i) && (i <= mLastFb))
476 continue;
477
478 if (!(layer.flags & HWC_SKIP_RENDERING) && ((layer.compositionType == HWC_OVERLAY) ||
479 ((mFbNeeded == true || this->mVirtualOverlayFlag) && layer.compositionType == HWC_FRAMEBUFFER_TARGET))) {
480 int dup_fd = dup(fence);
481 DISPLAY_LOGD(eDebugFence, "%d layer[type: %d, dst: %d, %d, %d, %d] fence is duplicated(%d)",
482 i, layer.compositionType,
483 layer.displayFrame.left, layer.displayFrame.top,
484 layer.displayFrame.right, layer.displayFrame.bottom,
485 dup_fd);
486 if (dup_fd < 0)
487 DISPLAY_LOGW("release fence dup failed: %s", strerror(errno));
488 if (mLayerInfos[i]->mInternalMPP != NULL) {
489 ExynosMPPModule *exynosMPP = mLayerInfos[i]->mInternalMPP;
490 if (mLayerInfos[i]->mInternalMPP->mDstBufFence[0] >= 0)
491 close(mLayerInfos[i]->mInternalMPP->mDstBufFence[0]);
492 exynosMPP->mDstBufFence[0] = dup(fence);
493 }
494 if (mLayerInfos[i]->mExternalMPP != NULL) {
495 ExynosMPPModule *exysnosMPP = mLayerInfos[i]->mExternalMPP;
496 if (exysnosMPP->mDstBufFence[exysnosMPP->mCurrentBuf] >= 0) {
497 close (exysnosMPP->mDstBufFence[exysnosMPP->mCurrentBuf]);
498 exysnosMPP->mDstBufFence[exysnosMPP->mCurrentBuf] = -1;
499 }
500 exysnosMPP->mDstBufFence[exysnosMPP->mCurrentBuf] = dup_fd;
501 exysnosMPP->mCurrentBuf = (exysnosMPP->mCurrentBuf + 1) % exysnosMPP->mNumAvailableDstBuffers;
502 } else {
503 if (this->mVirtualOverlayFlag && (layer.compositionType == HWC_FRAMEBUFFER_TARGET)) {
504 if (layer.releaseFenceFd >= 0)
505 close(layer.releaseFenceFd);
506 }
507 layer.releaseFenceFd = dup_fd;
508 }
509 }
510 }
511
512 #if defined(USES_DUAL_DISPLAY)
513 if (mType == EXYNOS_SECONDARY_DISPLAY)
514 contents->retireFenceFd = dup(fence);
515 else
516 contents->retireFenceFd = fence;
517 #else
518 contents->retireFenceFd = fence;
519 #endif
520 }
521
522 void ExynosDisplay::dump(android::String8& result)
523 {
524 result.append(
525 " type | handle | color | blend | pa | format | position | size | intMPP | extMPP \n"
526 "----------+--------------|----------+-------+----+---------------+---------------+----------------------------------\n");
527 // 8_______ | 12__________ | 8_______ | 5____ | 2_ | 13___________ | [5____,5____] | [5____,5____] | [2_,2_] | [2_,2_]\n"
528
529 for (size_t i = 0; i < NUM_HW_WINDOWS; i++) {
530 struct decon_win_config &config = mLastConfigData.config[i];
531 if ((config.state == config.DECON_WIN_STATE_DISABLED) &&
532 (mLastMPPMap[i].internal_mpp.type == -1) &&
533 (mLastMPPMap[i].external_mpp.type == -1)){
534 result.appendFormat(" %8s | %12s | %8s | %5s | %2s | %13s | %13s | %13s",
535 "OVERLAY", "-", "-", "-", "-", "-", "-", "-");
536 }
537 else {
538 if (config.state == config.DECON_WIN_STATE_COLOR)
539 result.appendFormat(" %8s | %12s | %8x | %5s | %2s | %13s", "COLOR",
540 "-", config.color, "-", "-", "-");
541 else
542 result.appendFormat(" %8s | %12" PRIxPTR " | %8s | %5x | %2x | %13s",
543 mLastFbWindow == i ? "FB" : "OVERLAY",
544 intptr_t(mLastHandles[i]),
545 "-", config.blending, config.plane_alpha, deconFormat2str(config.format));
546
547 result.appendFormat(" | [%5d,%5d] | [%5u,%5u]", config.dst.x, config.dst.y,
548 config.dst.w, config.dst.h);
549 }
550 if (mLastMPPMap[i].internal_mpp.type == -1) {
551 result.appendFormat(" | [%2s,%2s]", "-", "-");
552 } else {
553 result.appendFormat(" | [%2d,%2d]", mLastMPPMap[i].internal_mpp.type, mLastMPPMap[i].internal_mpp.index);
554 }
555
556 if (mLastMPPMap[i].external_mpp.type == -1) {
557 result.appendFormat(" | [%2s,%2s]", "-", "-");
558 } else {
559 result.appendFormat(" | [%2d,%2d]", mLastMPPMap[i].external_mpp.type, mLastMPPMap[i].external_mpp.index);
560 }
561 result.append("\n");
562 }
563 }
564
565 void ExynosDisplay::freeMPP()
566 {
567 }
568
569 void ExynosDisplay::doPreProcessing(hwc_display_contents_1_t* contents)
570 {
571 mPreProcessedInfo.mHasDrmSurface = false;
572 mForceOverlayLayerIndex = -1;
573 this->mHasDrmSurface = false;
574 mYuvLayers = 0;
575 mLayersNeedScaling = false;
576
577 for (size_t i = 0; i < contents->numHwLayers; i++) {
578 hwc_layer_1_t &layer = contents->hwLayers[i];
579 if (layer.handle) {
580 private_handle_t *h = private_handle_t::dynamicCast(layer.handle);
581 if (h->flags & GRALLOC_USAGE_PROTECTED) {
582 mPreProcessedInfo.mHasDrmSurface = true;
583 this->mHasDrmSurface = true;
584 mForceOverlayLayerIndex = i;
585 }
586 if (!isFormatRgb(h->format)) {
587 this->mYuvLayers++;
588 }
589 if (isScaled(layer))
590 mLayersNeedScaling = true;
591 }
592 }
593 }
594
595 void ExynosDisplay::allocateLayerInfos(hwc_display_contents_1_t* contents)
596 {
597 if (contents == NULL)
598 return;
599
600 if (!mLayerInfos.isEmpty()) {
601 for (size_t i = 0; i < mLayerInfos.size(); i++) {
602 delete mLayerInfos[i];
603 }
604 mLayerInfos.clear();
605 }
606
607 for (size_t i= 0; i < contents->numHwLayers; i++) {
608 ExynosLayerInfo *layerInfo = new ExynosLayerInfo();
609 memset(layerInfo, 0, sizeof(ExynosLayerInfo));
610 layerInfo->mDmaType = -1;
611 mLayerInfos.push(layerInfo);
612 }
613
614 mForceFb = mHwc->force_gpu;
615
616 doPreProcessing(contents);
617 }
618
619 void ExynosDisplay::dumpLayerInfo(android::String8& result)
620 {
621 if (!mLayerInfos.isEmpty()) {
622 result.append(
623 " type | CheckOverlayFlag | CheckMPPFlag | Comp | mWinIndex | mDmaType | mIntMPP | mExtMPP \n"
624 "------------+------------------+--------------+------+-----------+----------+-----------+----------\n");
625 // 10________ | 8_______ | 8_______ | 3__ | 9________ | 8_______ | [3__, 2_] | [3__, 2_]\n"
626 for (size_t i = 0; i < mLayerInfos.size(); i++) {
627 unsigned int type = mLayerInfos[i]->compositionType;
628 static char const* compositionTypeName[] = {
629 "GLES",
630 "HWC",
631 "BACKGROUND",
632 "FB TARGET",
633 "UNKNOWN"};
634
635 if (type >= NELEM(compositionTypeName))
636 type = NELEM(compositionTypeName) - 1;
637 result.appendFormat(
638 " %10s | 0x%8x | 0x%8x | %1s | %9d | %8d",
639 compositionTypeName[type],
640 mLayerInfos[i]->mCheckOverlayFlag, mLayerInfos[i]->mCheckMPPFlag,
641 mLayerInfos[i]->mCompressed ? "Y" : "N",
642 mLayerInfos[i]->mWindowIndex, mLayerInfos[i]->mDmaType);
643
644 if (mLayerInfos[i]->mInternalMPP == NULL)
645 result.appendFormat(" | [%3s, %2s]", "-", "-");
646 else {
647 result.appendFormat(" | [%3s, %2d]", mLayerInfos[i]->mInternalMPP->getName().string(), mLayerInfos[i]->mInternalMPP->mIndex);
648 }
649
650 if (mLayerInfos[i]->mExternalMPP == NULL)
651 result.appendFormat(" | [%3s, %2s]", "-", "-");
652 else {
653 result.appendFormat(" | [%3s, %2d]", mLayerInfos[i]->mExternalMPP->getName().string(), mLayerInfos[i]->mExternalMPP->mIndex);
654 }
655 result.append("\n");
656 }
657 }
658 result.append("\n");
659 }
660
661 bool ExynosDisplay::handleTotalBandwidthOverload(hwc_display_contents_1_t *contents)
662 {
663 bool changed = false;
664 bool addFB = true;
665 if (mHwc->totPixels >= FIMD_TOTAL_BW_LIMIT) {
666 changed = true;
667 if (mFbNeeded) {
668 for (int i = mFirstFb - 1; i >= 0; i--) {
669 if (mForceOverlayLayerIndex == 0 && i == 0)
670 break;
671 hwc_layer_1_t &layer = contents->hwLayers[i];
672 layer.compositionType = HWC_FRAMEBUFFER;
673 mLayerInfos[i]->compositionType = layer.compositionType;
674 mLayerInfos[i]->mCheckOverlayFlag |= eInsufficientBandwidth;
675 mLayerInfos[i]->mInternalMPP = NULL;
676 mLayerInfos[i]->mExternalMPP = NULL;
677 mFirstFb = (size_t)i;
678 mHwc->totPixels -= WIDTH(layer.displayFrame) * HEIGHT(layer.displayFrame);
679 if (mHwc->totPixels < FIMD_TOTAL_BW_LIMIT)
680 break;
681 }
682 if (mHwc->totPixels >= FIMD_TOTAL_BW_LIMIT) {
683 for (size_t i = mLastFb + 1; i < contents->numHwLayers - 1; i++) {
684 hwc_layer_1_t &layer = contents->hwLayers[i];
685 layer.compositionType = HWC_FRAMEBUFFER;
686 mLayerInfos[i]->compositionType = layer.compositionType;
687 mLayerInfos[i]->mCheckOverlayFlag |= eInsufficientBandwidth;
688 mLayerInfos[i]->mInternalMPP = NULL;
689 mLayerInfos[i]->mExternalMPP = NULL;
690 mLastFb = i;
691 mHwc->totPixels -= WIDTH(layer.displayFrame) * HEIGHT(layer.displayFrame);
692 if (mHwc->totPixels < FIMD_TOTAL_BW_LIMIT)
693 break;
694 }
695 }
696 } else {
697 for (size_t i = 0; i < contents->numHwLayers; i++) {
698 hwc_layer_1_t &layer = contents->hwLayers[i];
699 if (layer.compositionType == HWC_OVERLAY &&
700 mForceOverlayLayerIndex != (int)i) {
701 layer.compositionType = HWC_FRAMEBUFFER;
702 mLastFb = max(mLastFb, i);
703 mLayerInfos[i]->compositionType = layer.compositionType;
704 mLayerInfos[i]->mCheckOverlayFlag |= eInsufficientBandwidth;
705 mLayerInfos[i]->mInternalMPP = NULL;
706 mLayerInfos[i]->mExternalMPP = NULL;
707 if (addFB) {
708 addFB = false;
709 mHwc->totPixels += mXres * mYres;
710 }
711 mHwc->totPixels -= WIDTH(layer.displayFrame) * HEIGHT(layer.displayFrame);
712 if (mHwc->totPixels < FIMD_TOTAL_BW_LIMIT)
713 break;
714 }
715 }
716 if (mForceOverlayLayerIndex == 0)
717 mFirstFb = 1;
718 else
719 mFirstFb = 0;
720 }
721 mFbNeeded = true;
722 }
723
724 return changed;
725 }
726
727 int ExynosDisplay::clearDisplay()
728 {
729 struct decon_win_config_data win_data;
730 memset(&win_data, 0, sizeof(win_data));
731
732 int ret = ioctl(this->mDisplayFd, S3CFB_WIN_CONFIG, &win_data);
733 LOG_ALWAYS_FATAL_IF(ret < 0,
734 "%s ioctl S3CFB_WIN_CONFIG failed to clear screen: %s",
735 mDisplayName.string(), strerror(errno));
736 // the causes of an empty config failing are all unrecoverable
737
738 return win_data.fence;
739 }
740
741 int ExynosDisplay::getCompModeSwitch()
742 {
743 unsigned int tot_win_size = 0, updateFps = 0;
744 unsigned int lcd_size = this->mXres * this->mYres;
745 uint64_t TimeStampDiff;
746 float Temp;
747
748 if (!mHwc->hwc_ctrl.dynamic_recomp_mode) {
749 mHwc->LastModeSwitchTimeStamp = 0;
750 mHwc->CompModeSwitch = NO_MODE_SWITCH;
751 return 0;
752 }
753
754 /* initialize the Timestamps */
755 if (!mHwc->LastModeSwitchTimeStamp) {
756 mHwc->LastModeSwitchTimeStamp = mHwc->LastUpdateTimeStamp;
757 mHwc->CompModeSwitch = NO_MODE_SWITCH;
758 return 0;
759 }
760
761 /* If video layer is there, skip the mode switch */
762 if (mYuvLayers || mLayersNeedScaling) {
763 if (mHwc->CompModeSwitch != HWC_2_GLES) {
764 return 0;
765 } else {
766 mHwc->CompModeSwitch = GLES_2_HWC;
767 mHwc->updateCallCnt = 0;
768 mHwc->LastModeSwitchTimeStamp = mHwc->LastUpdateTimeStamp;
769 DISPLAY_LOGI("[DYNAMIC_RECOMP] GLES_2_HWC by video layer");
770 return GLES_2_HWC;
771 }
772 }
773
774 /* Mode Switch is not required if total pixels are not more than the threshold */
775 if ((uint32_t)mHwc->incomingPixels <= lcd_size * HWC_FIMD_BW_TH) {
776 if (mHwc->CompModeSwitch != HWC_2_GLES) {
777 return 0;
778 } else {
779 mHwc->CompModeSwitch = GLES_2_HWC;
780 mHwc->updateCallCnt = 0;
781 mHwc->LastModeSwitchTimeStamp = mHwc->LastUpdateTimeStamp;
782 DISPLAY_LOGI("[DYNAMIC_RECOMP] GLES_2_HWC by BW check");
783 return GLES_2_HWC;
784 }
785 }
786
787 /*
788 * There will be at least one composition call per one minute (because of time update)
789 * To minimize the analysis overhead, just analyze it once in a second
790 */
791 TimeStampDiff = systemTime(SYSTEM_TIME_MONOTONIC) - mHwc->LastModeSwitchTimeStamp;
792
793 /*
794 * previous CompModeSwitch was GLES_2_HWC: check fps every 250ms from LastModeSwitchTimeStamp
795 * previous CompModeSwitch was HWC_2_GLES: check immediately
796 */
797 if ((mHwc->CompModeSwitch != HWC_2_GLES) && (TimeStampDiff < (VSYNC_INTERVAL * 15))) {
798 return 0;
799 }
800 mHwc->LastModeSwitchTimeStamp = mHwc->LastUpdateTimeStamp;
801 if ((mHwc->update_event_cnt != 1) && // This is not called by hwc_update_stat_thread
802 (mHwc->CompModeSwitch == HWC_2_GLES) && (mHwc->updateCallCnt == 1)) {
803 DISPLAY_LOGI("[DYNAMIC_RECOMP] first frame after HWC_2_GLES");
804 updateFps = HWC_FPS_TH;
805 } else {
806 Temp = (VSYNC_INTERVAL * 60) / TimeStampDiff;
807 updateFps = (int)(mHwc->updateCallCnt * Temp + 0.5);
808 }
809 mHwc->updateCallCnt = 0;
810 /*
811 * FPS estimation.
812 * If FPS is lower than HWC_FPS_TH, try to switch the mode to GLES
813 */
814 if (updateFps < HWC_FPS_TH) {
815 if (mHwc->CompModeSwitch != HWC_2_GLES) {
816 mHwc->CompModeSwitch = HWC_2_GLES;
817 DISPLAY_LOGI("[DYNAMIC_RECOMP] HWC_2_GLES by low FPS(%d)", updateFps);
818 return HWC_2_GLES;
819 } else {
820 return 0;
821 }
822 } else {
823 if (mHwc->CompModeSwitch == HWC_2_GLES) {
824 mHwc->CompModeSwitch = GLES_2_HWC;
825 DISPLAY_LOGI("[DYNAMIC_RECOMP] GLES_2_HWC by high FPS(%d)", updateFps);
826 return GLES_2_HWC;
827 } else {
828 return 0;
829 }
830 }
831
832 return 0;
833 }
834
835 int32_t ExynosDisplay::getDisplayAttributes(const uint32_t attribute, uint32_t __unused config)
836 {
837 switch(attribute) {
838 case HWC_DISPLAY_VSYNC_PERIOD:
839 return this->mVsyncPeriod;
840
841 case HWC_DISPLAY_WIDTH:
842 #if defined(USES_DUAL_DISPLAY)
843 if ((mType == EXYNOS_PRIMARY_DISPLAY) || (mType == EXYNOS_SECONDARY_DISPLAY))
844 return this->mXres/2;
845 else
846 return mXres;
847 #else
848 return this->mXres;
849 #endif
850
851 case HWC_DISPLAY_HEIGHT:
852 return this->mYres;
853
854 case HWC_DISPLAY_DPI_X:
855 return this->mXdpi;
856
857 case HWC_DISPLAY_DPI_Y:
858 return this->mYdpi;
859
860 default:
861 DISPLAY_LOGE("unknown display attribute %u", attribute);
862 return -EINVAL;
863 }
864 }
865
866 bool ExynosDisplay::isOverlaySupportedByIDMA(hwc_layer_1_t __unused &layer, size_t __unused index)
867 {
868 if (isCompressed(layer))
869 return false;
870 else
871 return true;
872 }
873
874 void ExynosDisplay::getIDMAMinSize(hwc_layer_1_t __unused &layer, int *w, int *h)
875 {
876 *w = 1;
877 *h = 1;
878 }
879
880 bool ExynosDisplay::isOverlaySupported(hwc_layer_1_t &layer, size_t index, bool useVPPOverlay,
881 ExynosMPPModule** supportedInternalMPP, ExynosMPPModule** supportedExternalMPP)
882 {
883 int mMPPIndex = 0;
884 int ret = 0;
885 ExynosMPPModule* transitionInternalMPP = NULL;
886 private_handle_t *handle = NULL;
887 int handleFormat = 0;
888 bool firstFrameFramebufferTarget = false;
889
890 DISPLAY_LOGD(eDebugOverlaySupported, "isOverlaySupported:: index(%d), useVPPOverlay(%d)", index, useVPPOverlay);
891
892 if (layer.flags & HWC_SKIP_LAYER) {
893 mLayerInfos[index]->mCheckOverlayFlag |= eSkipLayer;
894 DISPLAY_LOGD(eDebugOverlaySupported, "\tlayer %u: skipping", index);
895 return false;
896 }
897
898 if (!layer.planeAlpha)
899 return true;
900
901 if (index == 0 && layer.planeAlpha < 255) {
902 DISPLAY_LOGD(eDebugOverlaySupported, "\tlayer %u: eUnsupportedPlaneAlpha", index);
903 mLayerInfos[index]->mCheckOverlayFlag |= eUnsupportedPlaneAlpha;
904 return false;
905 }
906
907 if (layer.handle) {
908 handle = private_handle_t::dynamicCast(layer.handle);
909 handleFormat = handle->format;
910 }
911
912 if ((layer.compositionType != HWC_FRAMEBUFFER_TARGET) && !handle) {
913 DISPLAY_LOGD(eDebugOverlaySupported, "\tlayer %u: handle is NULL, type is %d", index, layer.compositionType);
914 mLayerInfos[index]->mCheckOverlayFlag |= eInvalidHandle;
915 return false;
916 }
917
918 if (!handle && (layer.compositionType == HWC_FRAMEBUFFER_TARGET)) {
919 firstFrameFramebufferTarget = true;
920 handleFormat = HAL_PIXEL_FORMAT_RGBA_8888;
921 }
922
923 if (handle && (getDrmMode(handle->flags) == NO_DRM) &&
924 (isFloat(layer.sourceCropf.left) || isFloat(layer.sourceCropf.top) ||
925 isFloat(layer.sourceCropf.right - layer.sourceCropf.left) ||
926 isFloat(layer.sourceCropf.bottom - layer.sourceCropf.top))) {
927 if (isSourceCropfSupported(layer) == false)
928 return false;
929 }
930
931 if (!isBlendingSupported(layer.blending)) {
932 DISPLAY_LOGD(eDebugOverlaySupported, "\tlayer %u: blending %d not supported", index, layer.blending);
933 mLayerInfos[index]->mCheckOverlayFlag |= eUnsupportedBlending;
934 return false;
935 }
936
937 int32_t bpp = formatToBpp(handleFormat);
938 int32_t left = max(layer.displayFrame.left, 0);
939 int32_t right = min(layer.displayFrame.right, mXres);
940 uint32_t visible_width = 0;
941
942 if ((bpp == 16) &&
943 ((layer.displayFrame.left % 2 != 0) || (layer.displayFrame.right % 2 != 0))) {
944 DISPLAY_LOGD(eDebugOverlaySupported, "\tlayer %u: eNotAlignedDstPosition", index);
945 mLayerInfos[index]->mCheckOverlayFlag |= eNotAlignedDstPosition;
946 return false;
947 }
948
949 visible_width = (right - left) * bpp / 8;
950 if (visible_width < BURSTLEN_BYTES) {
951 #ifdef USE_DRM_BURST_LEN
952 if (handle && (getDrmMode(handle->flags) != NO_DRM)) {
953 if (visible_width < DRM_BURSTLEN_BYTES) {
954 DISPLAY_LOGD(eDebugOverlaySupported, "\tlayer %u: visible area is too narrow", index);
955 mLayerInfos[index]->mCheckOverlayFlag |= eUnsupportedDstWidth;
956 return false;
957 }
958 } else {
959 #endif
960 DISPLAY_LOGD(eDebugOverlaySupported, "\tlayer %u: visible area is too narrow", index);
961 mLayerInfos[index]->mCheckOverlayFlag |= eUnsupportedDstWidth;
962 return false;
963 #ifdef USE_DRM_BURST_LEN
964 }
965 #endif
966 }
967
968 if (!isProcessingRequired(layer) && !useVPPOverlay)
969 return true;
970
971 hwc_layer_1_t extMPPOutLayer = layer;
972 int originalHandleFormt = handleFormat;
973 int dst_format = handleFormat;
974 bool isBothMPPUsed = isBothMPPProcessingRequired(layer, &extMPPOutLayer);
975 DISPLAY_LOGD(eDebugOverlaySupported, "isOverlaySupported:: index(%d), isBothMPPUsed(%d)", index, isBothMPPUsed);
976
977 if (isBothMPPUsed) {
978 if ((*supportedInternalMPP != NULL) && (*supportedExternalMPP != NULL))
979 return true;
980 } else {
981 if ((*supportedInternalMPP != NULL) || (*supportedExternalMPP != NULL && !useVPPOverlay))
982 return true;
983 }
984
985 if (*supportedExternalMPP == NULL && isBothMPPUsed)
986 {
987 /* extMPPOutLayer is output of ExtMPP
988 * The output of ExtMPP is the input of IntMPP
989 */
990 if (!isFormatRgb(handleFormat) &&
991 (WIDTH(extMPPOutLayer.displayFrame) % mCheckIntMPP->getCropWidthAlign(layer) != 0 ||
992 HEIGHT(extMPPOutLayer.displayFrame) % mCheckIntMPP->getCropHeightAlign(layer) != 0 ||
993 !(mCheckIntMPP->isFormatSupportedByMPP(handleFormat)) ||
994 !(mCheckIntMPP->isCSCSupportedByMPP(handleFormat, HAL_PIXEL_FORMAT_RGBX_8888, layer.dataSpace))))
995 dst_format = mExternalMPPDstFormat;
996
997 /* extMPPOutLayer is output of ExtMPP */
998 for (size_t i = 0; i < mExternalMPPs.size(); i++)
999 {
1000 ExynosMPPModule* externalMPP = mExternalMPPs[i];
1001 if (externalMPP->mState == MPP_STATE_FREE) {
1002 ret = externalMPP->isProcessingSupported(extMPPOutLayer, dst_format);
1003 if (ret > 0) {
1004 *supportedExternalMPP = externalMPP;
1005 break;
1006 } else {
1007 mLayerInfos[index]->mCheckMPPFlag |= -ret;
1008 }
1009 }
1010 }
1011
1012 /* Can't find valid externalMPP */
1013 if (*supportedExternalMPP == NULL) {
1014 DISPLAY_LOGD(eDebugOverlaySupported, "\tlayer %u: Can't find valid externalMPP", index);
1015 mLayerInfos[index]->mCheckOverlayFlag |= eInsufficientMPP;
1016 return false;
1017 }
1018 }
1019 if (*supportedInternalMPP == NULL) {
1020 for (size_t i = 0; i < mInternalMPPs.size(); i++)
1021 {
1022 ExynosMPPModule* internalMPP = mInternalMPPs[i];
1023 hwc_layer_1_t extMPPTempOutLayer = extMPPOutLayer;
1024 if (isBothMPPUsed) {
1025 if (internalMPP->mType == MPP_VPP_G)
1026 continue;
1027 /* extMPPOutLayer is output of ExtMPP
1028 * The output of ExtMPP is the input of IntMPP
1029 */
1030 if (!isFormatRgb(handleFormat) &&
1031 (WIDTH(extMPPTempOutLayer.displayFrame) % internalMPP->getCropWidthAlign(layer) != 0 ||
1032 HEIGHT(extMPPTempOutLayer.displayFrame) % internalMPP->getCropHeightAlign(layer) != 0 ||
1033 !(internalMPP->isFormatSupportedByMPP(handleFormat))))
1034 dst_format = mExternalMPPDstFormat;
1035
1036 extMPPTempOutLayer.sourceCropf.left = extMPPOutLayer.displayFrame.left;
1037 extMPPTempOutLayer.sourceCropf.top = extMPPOutLayer.displayFrame.top;
1038 extMPPTempOutLayer.sourceCropf.right = extMPPOutLayer.displayFrame.right;
1039 extMPPTempOutLayer.sourceCropf.bottom = extMPPOutLayer.displayFrame.bottom;
1040 extMPPTempOutLayer.displayFrame.left = layer.displayFrame.left;
1041 extMPPTempOutLayer.displayFrame.top = layer.displayFrame.top;
1042 extMPPTempOutLayer.displayFrame.right = layer.displayFrame.right;
1043 extMPPTempOutLayer.displayFrame.bottom = layer.displayFrame.bottom;
1044 ((private_handle_t *)extMPPTempOutLayer.handle)->format = dst_format;
1045 extMPPTempOutLayer.transform = 0;
1046 }
1047 ExynosDisplay *addedDisplay = (mHwc->hdmi_hpd ? (ExynosDisplay *)mHwc->externalDisplay : (ExynosDisplay *)mHwc->virtualDisplay);
1048 ExynosDisplay *otherDisplay = (mType ? (ExynosDisplay *)mHwc->primaryDisplay : addedDisplay);
1049
1050 /*
1051 * If MPP was assigned to other Device in previous frame
1052 * then doesn't assign it untill it is cleared
1053 */
1054 if ((internalMPP->mState == MPP_STATE_FREE) &&
1055 (internalMPP->mDisplay == NULL || internalMPP->mDisplay == this)) {
1056 /* InternalMPP doesn't need to check dst_format. Set dst_format with source format */
1057 if (firstFrameFramebufferTarget)
1058 ret = 1;
1059 else {
1060 ret = internalMPP->isProcessingSupported(extMPPTempOutLayer, ((private_handle_t *)extMPPTempOutLayer.handle)->format);
1061 handle->format = originalHandleFormt;
1062 }
1063 if (ret > 0) {
1064 *supportedInternalMPP = internalMPP;
1065 return true;
1066 } else {
1067 mLayerInfos[index]->mCheckMPPFlag |= -ret;
1068 }
1069 } else if (internalMPP->wasUsedByDisplay(otherDisplay)) {
1070 DISPLAY_LOGD(eDebugOverlaySupported, "\tlayer %u: internalMPP[%d, %d] was used by other device", index, internalMPP->mType, internalMPP->mIndex);
1071 if (transitionInternalMPP == NULL)
1072 transitionInternalMPP = internalMPP;
1073 }
1074 if (handle)
1075 handle->format = originalHandleFormt;
1076 }
1077 }
1078
1079 if ((*supportedInternalMPP == NULL) && (useVPPOverlay == true) && !isProcessingRequired(layer)) {
1080 DISPLAY_LOGD(eDebugOverlaySupported, "\tlayer %u: eInsufficientMPP", index);
1081 mLayerInfos[index]->mCheckOverlayFlag |= eInsufficientMPP;
1082 if (transitionInternalMPP != NULL) {
1083 DISPLAY_LOGD(eDebugOverlaySupported, "\tlayer %u: internalMPP[%d, %d] transition is started", index, transitionInternalMPP->mType, transitionInternalMPP->mIndex);
1084 transitionInternalMPP->startTransition(this);
1085 }
1086 return false;
1087 }
1088
1089 /* Can't find valid internalMPP */
1090 if (isBothMPPProcessingRequired(layer) && *supportedInternalMPP == NULL) {
1091 DISPLAY_LOGD(eDebugOverlaySupported, "\tlayer %u: Can't find valid internalMPP", index);
1092 if (transitionInternalMPP != NULL) {
1093 DISPLAY_LOGD(eDebugOverlaySupported, "\tlayer %u: internalMPP[%d, %d] transition is started", index, transitionInternalMPP->mType, transitionInternalMPP->mIndex);
1094 transitionInternalMPP->startTransition(this);
1095 }
1096 mLayerInfos[index]->mCheckOverlayFlag |= eInsufficientMPP;
1097 return false;
1098 }
1099
1100 if (*supportedExternalMPP == NULL) {
1101 for (size_t i = 0; i < mExternalMPPs.size(); i++)
1102 {
1103 ExynosMPPModule* externalMPP = mExternalMPPs[i];
1104 int dst_format = handleFormat;
1105 if (!isFormatRgb(handleFormat))
1106 dst_format = mExternalMPPDstFormat;
1107
1108 if (externalMPP->mState == MPP_STATE_FREE) {
1109 if (firstFrameFramebufferTarget)
1110 ret = 1;
1111 else
1112 ret = externalMPP->isProcessingSupported(layer, dst_format);
1113 if (ret > 0) {
1114 *supportedExternalMPP = externalMPP;
1115 if (useVPPOverlay)
1116 break;
1117 return true;
1118 } else {
1119 mLayerInfos[index]->mCheckMPPFlag |= -ret;
1120 }
1121 }
1122 }
1123 }
1124
1125 if (*supportedExternalMPP != NULL && useVPPOverlay == true && *supportedInternalMPP == NULL) {
1126 int originalHandleFormt = handleFormat;
1127 dst_format = handleFormat;
1128 if (!isFormatRgb(handleFormat))
1129 dst_format = mExternalMPPDstFormat;
1130 for (size_t i = 0; i < mInternalMPPs.size(); i++)
1131 {
1132 extMPPOutLayer = layer;
1133 /* extMPPOutLayer is output of ExtMPP
1134 * The output of ExtMPP is the input of IntMPP
1135 */
1136 extMPPOutLayer.sourceCropf.left = layer.displayFrame.left;
1137 extMPPOutLayer.sourceCropf.top = layer.displayFrame.top;
1138 extMPPOutLayer.sourceCropf.right = layer.displayFrame.right;
1139 extMPPOutLayer.sourceCropf.bottom = layer.displayFrame.bottom;
1140 extMPPOutLayer.transform = 0;
1141 if (handle)
1142 ((private_handle_t *)extMPPOutLayer.handle)->format = dst_format;
1143 ExynosMPPModule* internalMPP = mInternalMPPs[i];
1144
1145 /*
1146 * If MPP was assigned to other Device in previous frame
1147 * then doesn't assign it untill it is cleared
1148 */
1149 if ((internalMPP->mState == MPP_STATE_FREE) &&
1150 (internalMPP->mDisplay == NULL || internalMPP->mDisplay == this)) {
1151 if (firstFrameFramebufferTarget)
1152 ret = 1;
1153 else {
1154 ret = internalMPP->isProcessingSupported(extMPPOutLayer, ((private_handle_t *)extMPPOutLayer.handle)->format);
1155 handle->format = originalHandleFormt;
1156 }
1157 if (ret > 0) {
1158 *supportedInternalMPP = internalMPP;
1159 return true;
1160 } else {
1161 mLayerInfos[index]->mCheckMPPFlag |= -ret;
1162 }
1163 } else {
1164 ExynosDisplay *addedDisplay = (mHwc->hdmi_hpd ? (ExynosDisplay *)mHwc->externalDisplay : (ExynosDisplay *)mHwc->virtualDisplay);
1165 ExynosDisplay *otherDisplay = (mType ? (ExynosDisplay *)mHwc->primaryDisplay : addedDisplay);
1166 if (firstFrameFramebufferTarget) {
1167 if ((internalMPP->wasUsedByDisplay(otherDisplay)) && (transitionInternalMPP == NULL))
1168 transitionInternalMPP = internalMPP;
1169 } else {
1170 if ((internalMPP->wasUsedByDisplay(otherDisplay)) &&
1171 ((transitionInternalMPP == NULL) ||
1172 ((transitionInternalMPP->isProcessingSupported(extMPPOutLayer, ((private_handle_t *)extMPPOutLayer.handle)->format) < 0) &&
1173 (internalMPP->isProcessingSupported(extMPPOutLayer, ((private_handle_t *)extMPPOutLayer.handle)->format) > 0))))
1174 transitionInternalMPP = internalMPP;
1175 }
1176 }
1177
1178 if (handle)
1179 handle->format = originalHandleFormt;
1180 }
1181 }
1182
1183 /* Transit display for next frame */
1184 if ((*supportedInternalMPP == NULL) && (transitionInternalMPP != NULL)) {
1185 DISPLAY_LOGD(eDebugOverlaySupported, "\tlayer %u: internalMPP[%d, %d] transition is started", index, transitionInternalMPP->mType, transitionInternalMPP->mIndex);
1186 transitionInternalMPP->startTransition(this);
1187 }
1188
1189 /* Can't find valid MPP */
1190 DISPLAY_LOGD(eDebugOverlaySupported, "\tlayer %u: can't find valid MPP", index);
1191 mLayerInfos[index]->mCheckOverlayFlag |= eInsufficientMPP;
1192 return false;
1193
1194 }
1195
1196 void ExynosDisplay::configureHandle(private_handle_t *handle, size_t index,
1197 hwc_layer_1_t &layer, int fence_fd, decon_win_config &cfg)
1198 {
1199 int isOpaque = 0;
1200
1201 if (handle == NULL)
1202 return;
1203
1204 #ifdef HWC_SET_OPAQUE
1205 if ((layer.flags & HWC_SET_OPAQUE) && handle && (handle->format == HAL_PIXEL_FORMAT_RGBA_8888)
1206 && (layer.compositionType == HWC_OVERLAY)) {
1207 handle->format = HAL_PIXEL_FORMAT_RGBX_8888;
1208 isOpaque = 1;
1209 }
1210 #endif
1211 hwc_frect_t &sourceCrop = layer.sourceCropf;
1212 hwc_rect_t &displayFrame = layer.compositionType == HWC_FRAMEBUFFER_TARGET ? mFbUpdateRegion : layer.displayFrame;
1213 int32_t blending = layer.blending;
1214 int32_t planeAlpha = layer.planeAlpha;
1215 uint32_t x, y;
1216 uint32_t w = WIDTH(displayFrame);
1217 uint32_t h = HEIGHT(displayFrame);
1218 uint8_t bpp = formatToBpp(handle->format);
1219 uint32_t offset = ((uint32_t)sourceCrop.top * handle->stride + (uint32_t)sourceCrop.left) * bpp / 8;
1220 ExynosMPPModule* internalMPP = mLayerInfos[index]->mInternalMPP;
1221 ExynosMPPModule* externalMPP = mLayerInfos[index]->mExternalMPP;
1222
1223 #ifdef USES_DECON_AFBC_DECODER
1224 cfg.compression = isCompressed(layer);
1225 #endif
1226
1227 if (displayFrame.left < 0) {
1228 unsigned int crop = -displayFrame.left;
1229 DISPLAY_LOGD(eDebugWinConfig, "layer off left side of screen; cropping %u pixels from left edge",
1230 crop);
1231 x = 0;
1232 w -= crop;
1233 offset += crop * bpp / 8;
1234 } else {
1235 x = displayFrame.left;
1236 }
1237
1238 if (displayFrame.right > this->mXres) {
1239 unsigned int crop = displayFrame.right - this->mXres;
1240 DISPLAY_LOGD(eDebugWinConfig, "layer off right side of screen; cropping %u pixels from right edge",
1241 crop);
1242 w -= crop;
1243 }
1244
1245 if (displayFrame.top < 0) {
1246 unsigned int crop = -displayFrame.top;
1247 DISPLAY_LOGD(eDebugWinConfig, "layer off top side of screen; cropping %u pixels from top edge",
1248 crop);
1249 y = 0;
1250 h -= crop;
1251 offset += handle->stride * crop * bpp / 8;
1252 } else {
1253 y = displayFrame.top;
1254 }
1255
1256 if (displayFrame.bottom > this->mYres) {
1257 int crop = displayFrame.bottom - this->mYres;
1258 DISPLAY_LOGD(eDebugWinConfig, "layer off bottom side of screen; cropping %u pixels from bottom edge",
1259 crop);
1260 h -= crop;
1261 }
1262
1263 cfg.fd_idma[0] = handle->fd;
1264 cfg.fd_idma[1] = handle->fd1;
1265 cfg.fd_idma[2] = handle->fd2;
1266 if (mLayerInfos[index]->mDmaType == -1) {
1267 cfg.state = cfg.DECON_WIN_STATE_DISABLED;
1268 } else {
1269 cfg.state = cfg.DECON_WIN_STATE_BUFFER;
1270 cfg.idma_type = (decon_idma_type)mLayerInfos[index]->mDmaType;
1271 }
1272 cfg.dst.x = x;
1273 cfg.dst.y = y;
1274 cfg.dst.w = w;
1275 cfg.dst.h = h;
1276 cfg.dst.f_w = mXres;
1277 cfg.dst.f_h = mYres;
1278 cfg.format = halFormatToS3CFormat(handle->format);
1279
1280 cfg.src.f_w = handle->stride;
1281 cfg.src.f_h = handle->vstride;
1282 if (handle->format == HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SP_M_PRIV) {
1283 if (handle->fd2 >= 0) {
1284 void *metaData = NULL;
1285 int interlacedType = -1;
1286 metaData = mmap(0, 64, PROT_READ|PROT_WRITE, MAP_SHARED, handle->fd2, 0);
1287 if (metaData)
1288 interlacedType = *(int *)metaData;
1289 else
1290 interlacedType = -1;
1291
1292 if (interlacedType == V4L2_FIELD_INTERLACED_TB ||
1293 interlacedType == V4L2_FIELD_INTERLACED_BT) {
1294 cfg.src.f_w = handle->stride * 2;
1295 cfg.src.f_h = handle->vstride / 2;
1296 }
1297 if (metaData)
1298 munmap(metaData, 64);
1299 }
1300 }
1301
1302 cfg.src.x = (int)sourceCrop.left;
1303 cfg.src.y = (int)sourceCrop.top;
1304
1305 if (cfg.src.x < 0)
1306 cfg.src.x = 0;
1307 if (cfg.src.y < 0)
1308 cfg.src.y = 0;
1309
1310 if (internalMPP != NULL) {
1311 if (cfg.src.f_w > (unsigned int)internalMPP->getMaxWidth(layer))
1312 cfg.src.f_w = (unsigned int)internalMPP->getMaxWidth(layer);
1313 if (cfg.src.f_h > (unsigned int)internalMPP->getMaxHeight(layer))
1314 cfg.src.f_h = (unsigned int)internalMPP->getMaxHeight(layer);
1315 cfg.src.f_w = ALIGN_DOWN((unsigned int)cfg.src.f_w, internalMPP->getSrcWidthAlign(layer));
1316 cfg.src.f_h = ALIGN_DOWN((unsigned int)cfg.src.f_h, internalMPP->getSrcHeightAlign(layer));
1317
1318 cfg.src.x = ALIGN((unsigned int)sourceCrop.left, internalMPP->getSrcXOffsetAlign(layer));
1319 cfg.src.y = ALIGN((unsigned int)sourceCrop.top, internalMPP->getSrcYOffsetAlign(layer));
1320 }
1321
1322 cfg.src.w = WIDTH(sourceCrop) - (cfg.src.x - (uint32_t)sourceCrop.left);
1323 if (cfg.src.x + cfg.src.w > cfg.src.f_w)
1324 cfg.src.w = cfg.src.f_w - cfg.src.x;
1325 cfg.src.h = HEIGHT(sourceCrop) - (cfg.src.y - (uint32_t)sourceCrop.top);
1326 if (cfg.src.y + cfg.src.h > cfg.src.f_h)
1327 cfg.src.h = cfg.src.f_h - cfg.src.y;
1328
1329 if (internalMPP != NULL) {
1330 if (cfg.src.w > (unsigned int)internalMPP->getMaxCropWidth(layer))
1331 cfg.src.w = (unsigned int)internalMPP->getMaxCropWidth(layer);
1332 if (cfg.src.h > (unsigned int)internalMPP->getMaxCropHeight(layer))
1333 cfg.src.h = (unsigned int)internalMPP->getMaxCropHeight(layer);
1334 cfg.src.w = ALIGN_DOWN(cfg.src.w, internalMPP->getCropWidthAlign(layer));
1335 cfg.src.h = ALIGN_DOWN(cfg.src.h, internalMPP->getCropHeightAlign(layer));
1336 }
1337
1338 if (isSrcCropFloat(layer.sourceCropf))
1339 {
1340 if (internalMPP != NULL) {
1341 exynos_mpp_img srcImg;
1342 internalMPP->adjustSourceImage(layer, srcImg);
1343 cfg.src.f_w = srcImg.fw;
1344 cfg.src.f_h = srcImg.fh;
1345 cfg.src.x = srcImg.x;
1346 cfg.src.y = srcImg.y;
1347 cfg.src.w = srcImg.w;
1348 cfg.src.h = srcImg.h;
1349 } else {
1350 if (externalMPP == NULL)
1351 ALOGE("float sourceCrop should be handled by MPP");
1352 }
1353 #if 0
1354 ALOGD("x = %7.1f, 0x%8x", sourceCrop.left, cfg.src.x);
1355 ALOGD("y = %7.1f, 0x%8x", sourceCrop.top, cfg.src.y);
1356 ALOGD("w = %7.1f, 0x%8x", sourceCrop.right - sourceCrop.left, cfg.src.w);
1357 ALOGD("h = %7.1f, 0x%8x", sourceCrop.bottom - sourceCrop.top, cfg.src.h);
1358 #endif
1359 }
1360
1361 cfg.blending = halBlendingToS3CBlending(blending);
1362 cfg.fence_fd = fence_fd;
1363 cfg.plane_alpha = 255;
1364 if (planeAlpha && (planeAlpha < 255)) {
1365 cfg.plane_alpha = planeAlpha;
1366 }
1367 if (mLayerInfos[index]->mInternalMPP) {
1368 cfg.vpp_parm.rot = (vpp_rotate)halTransformToHWRot(layer.transform);
1369 cfg.vpp_parm.eq_mode = isFullRangeColor(layer) ? BT_601_WIDE : BT_601_NARROW;
1370
1371 if ((!mLayerInfos[index]->mExternalMPP &&
1372 (mHwc->mS3DMode == S3D_MODE_READY || mHwc->mS3DMode == S3D_MODE_RUNNING) &&
1373 !isFormatRgb(handle->format)) &&
1374 mType == EXYNOS_PRIMARY_DISPLAY) {
1375 int S3DFormat = getS3DFormat(mHwc->mHdmiPreset);
1376 if (S3DFormat == S3D_SBS)
1377 cfg.src.w /= 2;
1378 else if (S3DFormat == S3D_TB)
1379 cfg.src.h /= 2;
1380 }
1381 }
1382 /* transparent region coordinates is on source buffer */
1383 //getLayerRegion(layer, cfg.transparent_area, eTransparentRegion);
1384 cfg.transparent_area.x += cfg.dst.x;
1385 cfg.transparent_area.y += cfg.dst.y;
1386
1387 /* opaque region coordinates is on screen */
1388 //getLayerRegion(layer, cfg.covered_opaque_area, eCoveredOpaqueRegion);
1389
1390 if (isOpaque && (handle->format == HAL_PIXEL_FORMAT_RGBX_8888)) {
1391 handle->format = HAL_PIXEL_FORMAT_RGBA_8888;
1392 isOpaque = 0;
1393 }
1394 }
1395
1396 void ExynosDisplay::configureOverlay(hwc_layer_1_t *layer, size_t index, decon_win_config &cfg)
1397 {
1398 if (layer->compositionType == HWC_BACKGROUND) {
1399 hwc_color_t color = layer->backgroundColor;
1400 cfg.state = cfg.DECON_WIN_STATE_COLOR;
1401 cfg.color = (color.r << 16) | (color.g << 8) | color.b;
1402 cfg.dst.x = 0;
1403 cfg.dst.y = 0;
1404 cfg.dst.w = this->mXres;
1405 cfg.dst.h = this->mYres;
1406 return;
1407 }
1408 private_handle_t *handle = private_handle_t::dynamicCast(layer->handle);
1409 hwc_frect_t originalCrop = layer->sourceCropf;
1410 if (layer->compositionType == HWC_FRAMEBUFFER_TARGET) {
1411 /* Adjust FbUpdateRegion */
1412 int minCropWidth = 0;
1413 int minCropHeight = 0;
1414 int cropWidthAlign = 1;
1415 if (mLayerInfos[index]->mInternalMPP != NULL) {
1416 minCropWidth = mLayerInfos[index]->mInternalMPP->getMinWidth(*layer);
1417 minCropHeight = mLayerInfos[index]->mInternalMPP->getMinHeight(*layer);
1418 cropWidthAlign = mLayerInfos[index]->mInternalMPP->getCropWidthAlign(*layer);
1419 } else {
1420 getIDMAMinSize(*layer, &minCropWidth, &minCropHeight);
1421 }
1422 #if defined(USES_DUAL_DISPLAY)
1423 int32_t minLeftPosition = (mType != EXYNOS_SECONDARY_DISPLAY)? 0:(mXres/2);
1424 int32_t maxRightPosition = (mType == EXYNOS_PRIMARY_DISPLAY)?(mXres/2):mXres;
1425 #else
1426 int32_t minLeftPosition = 0;
1427 int32_t maxRightPosition = mXres;
1428 #endif
1429 if (mFbUpdateRegion.left < minLeftPosition) mFbUpdateRegion.left = minLeftPosition;
1430 if (mFbUpdateRegion.right < minLeftPosition) mFbUpdateRegion.right = minLeftPosition;
1431 if (mFbUpdateRegion.left > maxRightPosition) mFbUpdateRegion.left = maxRightPosition;
1432 if (mFbUpdateRegion.right > maxRightPosition) mFbUpdateRegion.right = maxRightPosition;
1433 if (mFbUpdateRegion.top < 0) mFbUpdateRegion.top = 0;
1434 if (mFbUpdateRegion.bottom < 0) mFbUpdateRegion.bottom = 0;
1435 if (mFbUpdateRegion.top > mYres) mFbUpdateRegion.top = mYres;
1436 if (mFbUpdateRegion.bottom > mYres) mFbUpdateRegion.bottom = mYres;
1437
1438 if ((WIDTH(mFbUpdateRegion) % cropWidthAlign) != 0) {
1439 mFbUpdateRegion.left = ALIGN_DOWN(mFbUpdateRegion.left, cropWidthAlign);
1440 mFbUpdateRegion.right = ALIGN_UP(mFbUpdateRegion.right, cropWidthAlign);
1441 }
1442 if (WIDTH(mFbUpdateRegion) < minCropWidth) {
1443 #if defined(USES_DUAL_DISPLAY)
1444 if (mFbUpdateRegion.left + minCropWidth <= maxRightPosition)
1445 mFbUpdateRegion.right = mFbUpdateRegion.left + minCropWidth;
1446 else
1447 mFbUpdateRegion.left = mFbUpdateRegion.right - minCropWidth;
1448 #else
1449 if (mFbUpdateRegion.left + minCropWidth <= mXres)
1450 mFbUpdateRegion.right = mFbUpdateRegion.left + minCropWidth;
1451 else
1452 mFbUpdateRegion.left = mFbUpdateRegion.right - minCropWidth;
1453 #endif
1454 }
1455 if (HEIGHT(mFbUpdateRegion) < minCropHeight) {
1456 if (mFbUpdateRegion.top + minCropHeight <= mYres)
1457 mFbUpdateRegion.bottom = mFbUpdateRegion.top + minCropHeight;
1458 else
1459 mFbUpdateRegion.top = mFbUpdateRegion.bottom - minCropHeight;
1460 }
1461
1462 if ((mFbUpdateRegion.left >= minLeftPosition) && (mFbUpdateRegion.top >= 0) &&
1463 (mFbUpdateRegion.right <= maxRightPosition) && (mFbUpdateRegion.bottom <= mYres)) {
1464 #ifdef USES_DUAL_DISPLAY
1465 if (mType == EXYNOS_SECONDARY_DISPLAY) {
1466 layer->sourceCropf.left = (double)mFbUpdateRegion.left - (mXres/2);
1467 layer->sourceCropf.right = (double)mFbUpdateRegion.right - (mXres/2);
1468 } else {
1469 layer->sourceCropf.left = (double)mFbUpdateRegion.left;
1470 layer->sourceCropf.right = (double)mFbUpdateRegion.right;
1471 }
1472 #else
1473 layer->sourceCropf.left = (double)mFbUpdateRegion.left;
1474 layer->sourceCropf.right = (double)mFbUpdateRegion.right;
1475 #endif
1476 layer->sourceCropf.top = (double)mFbUpdateRegion.top;
1477 layer->sourceCropf.bottom = (double)mFbUpdateRegion.bottom;
1478 } else {
1479 mFbUpdateRegion = layer->displayFrame;
1480 }
1481 }
1482 configureHandle(handle, index, *layer, layer->acquireFenceFd, cfg);
1483 layer->sourceCropf = originalCrop;
1484 }
1485
1486 int ExynosDisplay::handleWindowUpdate(hwc_display_contents_1_t __unused *contents,
1487 struct decon_win_config __unused *config)
1488 {
1489 int layerIdx = -1;
1490 int updatedWinCnt = 0;
1491 int totalWinCnt = 0;
1492 int bitsPerPixel = 0;
1493 size_t winUpdateInfoIdx;
1494 hwc_rect updateRect = {this->mXres, this->mYres, 0, 0};
1495 hwc_rect currentRect = {0, 0, 0, 0};
1496 bool burstLengthCheckDone = false;
1497 int alignAdjustment = 1;
1498 int intersectionWidth = 0;
1499 int xAlign = 0;
1500 int wAlign = 0;
1501 int yAlign = 0;
1502 int hAlign = 0;
1503
1504 #if defined(USES_DUAL_DISPLAY)
1505 return -eWindowUpdateDisabled;
1506 #endif
1507
1508
1509 char value[PROPERTY_VALUE_MAX];
1510 property_get("debug.hwc.winupdate", value, "1");
1511
1512 if (!(!strcmp(value, "1") || !strcmp(value, "true")))
1513 return -eWindowUpdateDisabled;
1514
1515 if (DECON_WIN_UPDATE_IDX < 0)
1516 return -eWindowUpdateInvalidIndex;
1517 winUpdateInfoIdx = DECON_WIN_UPDATE_IDX;
1518
1519 if (contents->flags & HWC_GEOMETRY_CHANGED)
1520 return -eWindowUpdateGeometryChanged;
1521
1522 if (mPanelType == PANEL_DSC) {
1523 xAlign = this->mXres / mDSCHSliceNum;
1524 wAlign = this->mXres / mDSCHSliceNum;
1525 yAlign = mDSCYSliceSize;
1526 hAlign = mDSCYSliceSize;
1527 } else {
1528 xAlign = WINUPDATE_X_ALIGNMENT;
1529 wAlign = WINUPDATE_W_ALIGNMENT;
1530 yAlign = 1;
1531 hAlign = 1;
1532 }
1533
1534 for (size_t i = 0; i < contents->numHwLayers; i++) {
1535 if (contents->hwLayers[i].compositionType == HWC_FRAMEBUFFER)
1536 continue;
1537
1538 if (!mFbNeeded && contents->hwLayers[i].compositionType == HWC_FRAMEBUFFER_TARGET)
1539 continue;
1540 int32_t windowIndex = mLayerInfos[i]->mWindowIndex;
1541 if ((windowIndex < 0) || (windowIndex > MAX_DECON_WIN))
1542 return -eWindowUpdateInvalidConfig;
1543
1544 if (config[windowIndex].state != config[windowIndex].DECON_WIN_STATE_DISABLED) {
1545 totalWinCnt++;
1546
1547 if (winConfigChanged(&config[windowIndex], &this->mLastConfigData.config[windowIndex])) {
1548 updatedWinCnt++;
1549
1550 currentRect.left = config[windowIndex].dst.x;
1551 currentRect.right = config[windowIndex].dst.x + config[windowIndex].dst.w;
1552 currentRect.top = config[windowIndex].dst.y;
1553 currentRect.bottom = config[windowIndex].dst.y + config[windowIndex].dst.h;
1554
1555 if (hwcHasApiVersion((hwc_composer_device_1_t*)mHwc, HWC_DEVICE_API_VERSION_1_5))
1556 {
1557 private_handle_t *handle = NULL;
1558 hwc_rect damageRect = {0, 0, 0, 0};
1559 hwc_layer_1_t &layer = contents->hwLayers[i];
1560 if (layer.handle)
1561 handle = private_handle_t::dynamicCast(layer.handle);
1562 unsigned int damageRegionMod = getLayerRegion(layer, damageRect, eDamageRegion);
1563
1564 if (damageRegionMod == eDamageRegionSkip)
1565 continue;
1566
1567 if (handle && !isScaled(layer) && !isRotated(layer) && (damageRegionMod == eDamageRegionPartial)) {
1568 DISPLAY_LOGD(eDebugWindowUpdate, "[WIN_UPDATE][surfaceDamage] layer w(%4d) h(%4d), dirty (%4d, %4d) - (%4d, %4d)",
1569 handle->width, handle->height, damageRect.left, damageRect.top, damageRect.right, damageRect.bottom);
1570
1571 currentRect.left = config[windowIndex].dst.x - (int32_t)layer.sourceCropf.left + damageRect.left;
1572 currentRect.right = config[windowIndex].dst.x - (int32_t)layer.sourceCropf.left + damageRect.right;
1573 currentRect.top = config[windowIndex].dst.y - (int32_t)layer.sourceCropf.top + damageRect.top;
1574 currentRect.bottom = config[windowIndex].dst.y - (int32_t)layer.sourceCropf.top + damageRect.bottom;
1575 adjustRect(currentRect, mXres, mYres);
1576
1577 }
1578 }
1579
1580 if ((currentRect.left > currentRect.right) || (currentRect.top > currentRect.bottom)) {
1581 DISPLAY_LOGD(eDebugWindowUpdate, "[WIN_UPDATE] window(%d) layer(%d) invalid region (%4d, %4d) - (%4d, %4d)",
1582 i, layerIdx, currentRect.left, currentRect.top, currentRect.right, currentRect.bottom);
1583 return -eWindowUpdateInvalidRegion;
1584 }
1585 DISPLAY_LOGD(eDebugWindowUpdate, "[WIN_UPDATE] Updated Window(%d) Layer(%d) (%4d, %4d) - (%4d, %4d)",
1586 windowIndex, i, currentRect.left, currentRect.top, currentRect.right, currentRect.bottom);
1587 updateRect = expand(updateRect, currentRect);
1588 }
1589 }
1590 }
1591 if (updatedWinCnt == 0)
1592 return -eWindowUpdateNotUpdated;
1593
1594 /* Alignment check */
1595 for (size_t i = 0; i < contents->numHwLayers; i++) {
1596 if (contents->hwLayers[i].compositionType == HWC_FRAMEBUFFER)
1597 continue;
1598
1599 if (!mFbNeeded && contents->hwLayers[i].compositionType == HWC_FRAMEBUFFER_TARGET)
1600 continue;
1601
1602 int32_t windowIndex = mLayerInfos[i]->mWindowIndex;
1603 currentRect.left = config[windowIndex].dst.x;
1604 currentRect.right = config[windowIndex].dst.x + config[windowIndex].dst.w;
1605 currentRect.top = config[windowIndex].dst.y;
1606 currentRect.bottom = config[windowIndex].dst.y + config[windowIndex].dst.h;
1607
1608 if ((config[windowIndex].state != config[windowIndex].DECON_WIN_STATE_DISABLED) &&
1609 intersect(currentRect, updateRect)) {
1610 private_handle_t *handle = NULL;
1611 hwc_layer_1_t &layer = contents->hwLayers[i];
1612 if (layer.handle)
1613 handle = private_handle_t::dynamicCast(layer.handle);
1614 else
1615 return -eWindowUpdateInvalidConfig;
1616
1617 int originalFormat = handle->format;
1618 int originalTransform = layer.transform;
1619 if (mLayerInfos[i]->mInternalMPP != NULL) {
1620 /* VPP scaling case */
1621 if ((config[windowIndex].src.w != config[windowIndex].dst.w) ||
1622 (config[windowIndex].src.h != config[windowIndex].dst.h))
1623 return -eWindowUpdateUnsupportedUseCase;
1624
1625 handle->format = S3CFormatToHalFormat(config[windowIndex].format);
1626 if (handle->format >= 0) {
1627 /* rotation was handled by externalMPP */
1628 if (mLayerInfos[i]->mExternalMPP != NULL)
1629 layer.transform = 0;
1630 xAlign = getLCM(xAlign, mLayerInfos[i]->mInternalMPP->getSrcXOffsetAlign(layer));
1631 yAlign = getLCM(yAlign, mLayerInfos[i]->mInternalMPP->getSrcYOffsetAlign(layer));
1632 wAlign = getLCM(wAlign, mLayerInfos[i]->mInternalMPP->getCropWidthAlign(layer));
1633 hAlign = getLCM(hAlign, mLayerInfos[i]->mInternalMPP->getCropHeightAlign(layer));
1634 } else {
1635 handle->format = originalFormat;
1636 layer.transform = originalTransform;
1637 return -eWindowUpdateInvalidConfig;
1638 }
1639 }
1640 handle->format = originalFormat;
1641 layer.transform = originalTransform;
1642 }
1643 }
1644
1645 updateRect.left = ALIGN_DOWN(updateRect.left, xAlign);
1646 updateRect.top = ALIGN_DOWN(updateRect.top, yAlign);
1647
1648 if (HEIGHT(updateRect) < WINUPDATE_MIN_HEIGHT) {
1649 if (updateRect.top + WINUPDATE_MIN_HEIGHT <= mYres)
1650 updateRect.bottom = updateRect.top + WINUPDATE_MIN_HEIGHT;
1651 else
1652 updateRect.top = updateRect.bottom - WINUPDATE_MIN_HEIGHT;
1653 }
1654
1655 if ((100 * (WIDTH(updateRect) * HEIGHT(updateRect)) / (this->mXres * this->mYres)) > WINUPDATE_THRESHOLD)
1656 return -eWindowUpdateOverThreshold;
1657
1658 alignAdjustment = getLCM(alignAdjustment, xAlign);
1659 alignAdjustment = getLCM(alignAdjustment, wAlign);
1660
1661 while (1) {
1662 burstLengthCheckDone = true;
1663 updateRect.left = ALIGN_DOWN(updateRect.left, xAlign);
1664 if ((WIDTH(updateRect) % wAlign) != 0)
1665 updateRect.right = updateRect.left + ALIGN_DOWN(WIDTH(updateRect), wAlign) + wAlign;
1666 updateRect.top = ALIGN_DOWN(updateRect.top, yAlign);
1667 if ((HEIGHT(updateRect) % hAlign) != 0)
1668 updateRect.bottom = updateRect.top + ALIGN_DOWN(HEIGHT(updateRect), hAlign) + hAlign;
1669
1670 for (size_t i = 0; i < contents->numHwLayers; i++) {
1671 if (contents->hwLayers[i].compositionType == HWC_FRAMEBUFFER)
1672 continue;
1673 if (!mFbNeeded && contents->hwLayers[i].compositionType == HWC_FRAMEBUFFER_TARGET)
1674 continue;
1675 int32_t windowIndex = mLayerInfos[i]->mWindowIndex;
1676 if (config[windowIndex].state != config[windowIndex].DECON_WIN_STATE_DISABLED) {
1677 enum decon_pixel_format fmt = config[windowIndex].format;
1678 if (fmt == DECON_PIXEL_FORMAT_RGBA_5551 || fmt == DECON_PIXEL_FORMAT_RGB_565)
1679 bitsPerPixel = 16;
1680 else if (fmt == DECON_PIXEL_FORMAT_NV12 || fmt == DECON_PIXEL_FORMAT_NV21 ||
1681 fmt == DECON_PIXEL_FORMAT_NV12M || fmt == DECON_PIXEL_FORMAT_NV21M)
1682 bitsPerPixel = 12;
1683 else
1684 bitsPerPixel = 32;
1685
1686 currentRect.left = config[windowIndex].dst.x;
1687 currentRect.right = config[windowIndex].dst.x + config[windowIndex].dst.w;
1688 currentRect.top = config[windowIndex].dst.y;
1689 currentRect.bottom = config[windowIndex].dst.y + config[windowIndex].dst.h;
1690
1691 intersectionWidth = WIDTH(intersection(currentRect, updateRect));
1692
1693 DISPLAY_LOGD(eDebugWindowUpdate, "[WIN_UPDATE] win[%d] left(%d) right(%d) intersection(%d)", windowIndex, currentRect.left, currentRect.right, intersectionWidth);
1694
1695 if (intersectionWidth != 0 && (size_t)((intersectionWidth * bitsPerPixel) / 8) < BURSTLEN_BYTES) {
1696 #ifdef USE_DRM_BURST_LEN
1697 if (mHasDrmSurface) {
1698 if ((size_t)((intersectionWidth * bitsPerPixel) / 8) < DRM_BURSTLEN_BYTES) {
1699 DISPLAY_LOGD(eDebugWindowUpdate, "[WIN_UPDATE] win[%d] insufficient burst length (%d)*(%d) < %d", windowIndex, intersectionWidth, bitsPerPixel, BURSTLEN_BYTES);
1700 burstLengthCheckDone = false;
1701 break;
1702
1703 }
1704 } else {
1705 #endif
1706 DISPLAY_LOGD(eDebugWindowUpdate, "[WIN_UPDATE] win[%d] insufficient burst length (%d)*(%d) < %d", windowIndex, intersectionWidth, bitsPerPixel, BURSTLEN_BYTES);
1707 burstLengthCheckDone = false;
1708 break;
1709 #ifdef USE_DRM_BURST_LEN
1710 }
1711 #endif
1712 }
1713 }
1714 }
1715
1716 if (burstLengthCheckDone)
1717 break;
1718 DISPLAY_LOGD(eDebugWindowUpdate, "[WIN_UPDATE] Adjusting update width. current left(%d) right(%d)", updateRect.left, updateRect.right);
1719 if (updateRect.left >= alignAdjustment) {
1720 updateRect.left -= alignAdjustment;
1721 } else if (updateRect.right + alignAdjustment <= this->mXres) {
1722 updateRect.right += alignAdjustment;
1723 } else {
1724 DISPLAY_LOGD(eDebugWindowUpdate, "[WIN_UPDATE] Error during update width adjustment");
1725 return -eWindowUpdateAdjustmentFail;
1726 }
1727 }
1728
1729 config[winUpdateInfoIdx].state = config[winUpdateInfoIdx].DECON_WIN_STATE_UPDATE;
1730 config[winUpdateInfoIdx].dst.x = ALIGN_DOWN(updateRect.left, xAlign);
1731 if ((WIDTH(updateRect) % wAlign) != 0)
1732 updateRect.right = updateRect.left + ALIGN_DOWN(WIDTH(updateRect), wAlign) + wAlign;
1733 config[winUpdateInfoIdx].dst.w = WIDTH(updateRect);
1734
1735 config[winUpdateInfoIdx].dst.y = ALIGN_DOWN(updateRect.top, yAlign);
1736 if ((HEIGHT(updateRect) % hAlign) != 0)
1737 updateRect.bottom = updateRect.top + ALIGN_DOWN(HEIGHT(updateRect), hAlign) + hAlign;
1738 config[winUpdateInfoIdx].dst.h = HEIGHT(updateRect);
1739
1740 /* Final check */
1741 for (size_t i = 0; i < contents->numHwLayers; i++) {
1742 if (contents->hwLayers[i].compositionType == HWC_FRAMEBUFFER)
1743 continue;
1744
1745 if (!mFbNeeded && contents->hwLayers[i].compositionType == HWC_FRAMEBUFFER_TARGET)
1746 continue;
1747
1748 int32_t windowIndex = mLayerInfos[i]->mWindowIndex;
1749 currentRect.left = config[windowIndex].dst.x;
1750 currentRect.right = config[windowIndex].dst.x + config[windowIndex].dst.w;
1751 currentRect.top = config[windowIndex].dst.y;
1752 currentRect.bottom = config[windowIndex].dst.y + config[windowIndex].dst.h;
1753
1754 if ((config[windowIndex].state != config[windowIndex].DECON_WIN_STATE_DISABLED) &&
1755 intersect(currentRect, updateRect)) {
1756 private_handle_t *handle = NULL;
1757 hwc_rect intersect_rect = intersection(currentRect, updateRect);
1758 hwc_layer_1_t &layer = contents->hwLayers[i];
1759 if (layer.handle)
1760 handle = private_handle_t::dynamicCast(layer.handle);
1761 else
1762 return -eWindowUpdateInvalidConfig;
1763
1764 int originalFormat = handle->format;
1765 int originalTransform = layer.transform;
1766 if (mLayerInfos[i]->mInternalMPP != NULL) {
1767 handle->format = S3CFormatToHalFormat(config[windowIndex].format);
1768 /* rotation was handled by externalMPP */
1769 if (mLayerInfos[i]->mExternalMPP != NULL)
1770 layer.transform = 0;
1771 if (((mLayerInfos[i]->mInternalMPP->getSrcXOffsetAlign(layer) % intersect_rect.left) != 0) ||
1772 ((mLayerInfos[i]->mInternalMPP->getSrcYOffsetAlign(layer) % intersect_rect.top) != 0) ||
1773 ((mLayerInfos[i]->mInternalMPP->getCropWidthAlign(layer) % WIDTH(intersect_rect)) != 0) ||
1774 ((mLayerInfos[i]->mInternalMPP->getCropHeightAlign(layer) % HEIGHT(intersect_rect)) != 0)) {
1775 handle->format = originalFormat;
1776 layer.transform = originalTransform;
1777 config[winUpdateInfoIdx].state = config[winUpdateInfoIdx].DECON_WIN_STATE_DISABLED;
1778 return -eWindowUpdateAdjustmentFail;
1779 }
1780 }
1781 handle->format = originalFormat;
1782 layer.transform = originalTransform;
1783 }
1784 }
1785
1786 DISPLAY_LOGD(eDebugWindowUpdate, "[WIN_UPDATE] UpdateRegion cfg (%4d, %4d) w(%4d) h(%4d) updatedWindowCnt(%d)",
1787 config[winUpdateInfoIdx].dst.x, config[winUpdateInfoIdx].dst.y, config[winUpdateInfoIdx].dst.w, config[winUpdateInfoIdx].dst.h, updatedWinCnt);
1788
1789 /* Disable block mode if window update region is not full screen */
1790 if ((config[winUpdateInfoIdx].dst.x != 0) || (config[winUpdateInfoIdx].dst.y != 0) ||
1791 (config[winUpdateInfoIdx].dst.w != (uint32_t)mXres) || (config[winUpdateInfoIdx].dst.h != (uint32_t)mXres)) {
1792 for (size_t i = 0; i < NUM_HW_WINDOWS; i++) {
1793 memset(&config[i].transparent_area, 0, sizeof(config[i].transparent_area));
1794 #ifdef HWC_SET_OPAQUE
1795 memset(&config[i].covered_opaque_area, 0, sizeof(config[i].covered_opaque_area));
1796 #endif
1797 }
1798 }
1799
1800 return 1;
1801 }
1802
1803 void ExynosDisplay::getLayerRegion(hwc_layer_1_t &layer, decon_win_rect &rect_area, uint32_t regionType)
1804 {
1805 hwc_rect_t const *hwcRects = NULL;
1806 unsigned int numRects = 0;
1807 switch (regionType) {
1808 #if 0
1809 case eTransparentRegion:
1810 hwcRects = layer.transparentRegion.rects;
1811 numRects = layer.transparentRegion.numRects;
1812 break;
1813 case eCoveredOpaqueRegion:
1814 hwcRects = layer.coveredOpaqueRegion.rects;
1815 numRects = layer.coveredOpaqueRegion.numRects;
1816 break;
1817 #endif
1818 default:
1819 ALOGE("%s:: Invalid regionType (%d)", __func__, regionType);
1820 return;
1821 }
1822
1823 rect_area.x = rect_area.y = rect_area.w = rect_area.h = 0;
1824 if (hwcRects != NULL) {
1825 for (size_t j = 0; j < numRects; j++) {
1826 hwc_rect_t rect;
1827 rect.left = hwcRects[j].left;
1828 rect.top = hwcRects[j].top;
1829 rect.right = hwcRects[j].right;
1830 rect.bottom = hwcRects[j].bottom;
1831 adjustRect(rect, mXres, mYres);
1832 /* Find the largest rect */
1833 if ((rect_area.w * rect_area.h) <
1834 (uint32_t)(WIDTH(rect) * HEIGHT(rect))) {
1835 rect_area.x = rect.left;
1836 rect_area.y = rect.top;
1837 rect_area.w = WIDTH(rect);
1838 rect_area.h = HEIGHT(rect);
1839 }
1840 }
1841 }
1842 }
1843
1844 unsigned int ExynosDisplay::getLayerRegion(hwc_layer_1_t &layer, hwc_rect &rect_area, uint32_t regionType) {
1845 hwc_rect_t const *hwcRects = NULL;
1846 unsigned int numRects = 0;
1847
1848 switch (regionType) {
1849 case eDamageRegion:
1850 hwcRects = layer.surfaceDamage.rects;
1851 numRects = layer.surfaceDamage.numRects;
1852 break;
1853 default:
1854 ALOGE("%s:: Invalid regionType (%d)", __func__, regionType);
1855 return eDamageRegionError;
1856 }
1857
1858 if ((numRects == 0) || (hwcRects == NULL))
1859 return eDamageRegionFull;
1860
1861 if ((numRects == 1) && (hwcRects[0].left == 0) && (hwcRects[0].top == 0) &&
1862 (hwcRects[0].right == 0) && (hwcRects[0].bottom == 0))
1863 return eDamageRegionSkip;
1864
1865 rect_area.left = INT_MAX;
1866 rect_area.top = INT_MAX;
1867 rect_area.right = rect_area.bottom = 0;
1868 if (hwcRects != NULL) {
1869 for (size_t j = 0; j < numRects; j++) {
1870 hwc_rect_t rect;
1871 rect.left = hwcRects[j].left;
1872 rect.top = hwcRects[j].top;
1873 rect.right = hwcRects[j].right;
1874 rect.bottom = hwcRects[j].bottom;
1875 adjustRect(rect, INT_MAX, INT_MAX);
1876 /* Get sums of rects */
1877 rect_area = expand(rect_area, rect);
1878 }
1879 }
1880
1881 return eDamageRegionPartial;
1882 }
1883
1884 bool ExynosDisplay::getPreviousDRMDMA(int *dma)
1885 {
1886 *dma = -1;
1887
1888 for (size_t i = 0; i < NUM_HW_WINDOWS; i++) {
1889 if (mLastConfigData.config[i].protection == 1) {
1890 *dma = (int)mLastConfigData.config[i].idma_type;
1891 return true;
1892 }
1893 }
1894 return false;
1895 }
1896
1897 int ExynosDisplay::winconfigIoctl(decon_win_config_data *win_data)
1898 {
1899 ATRACE_CALL();
1900 return ioctl(this->mDisplayFd, S3CFB_WIN_CONFIG, win_data);
1901 }
1902
1903 int ExynosDisplay::postFrame(hwc_display_contents_1_t* contents)
1904 {
1905 ATRACE_CALL();
1906
1907 if (mWinData == NULL) {
1908 DISPLAY_LOGE("mWinData is not valid");
1909 return -1;
1910 }
1911 struct decon_win_config *config = mWinData->config;
1912 int win_map = 0;
1913 int tot_ovly_wins = 0;
1914 uint32_t rectCount = 0;
1915 int ret = 0;
1916
1917 memset(mLastHandles, 0, sizeof(mLastHandles));
1918 memset(mLastMPPMap, 0, sizeof(mLastMPPMap));
1919 memset(config, 0, sizeof(mWinData->config));
1920
1921 for (size_t i = 0; i < NUM_HW_WINDOWS; i++) {
1922 config[i].fence_fd = -1;
1923 mLastMPPMap[i].internal_mpp.type = -1;
1924 mLastMPPMap[i].external_mpp.type = -1;
1925 }
1926 for (size_t i = 0; i < contents->numHwLayers; i++) {
1927 hwc_layer_1_t &layer = contents->hwLayers[i];
1928 if (layer.handle) {
1929 private_handle_t *handle = private_handle_t::dynamicCast(layer.handle);
1930 if (handle->format == HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SP_M_PRIV
1931 && rectCount < mBackUpFrect.size())
1932 layer.sourceCropf = mBackUpFrect[rectCount++];
1933 }
1934 }
1935
1936 for (size_t i = 0; i < contents->numHwLayers; i++) {
1937 hwc_layer_1_t &layer = contents->hwLayers[i];
1938 int32_t window_index = mLayerInfos[i]->mWindowIndex;
1939 private_handle_t *handle = NULL;
1940 if (layer.handle)
1941 handle = private_handle_t::dynamicCast(layer.handle);
1942
1943 if ((layer.flags & HWC_SKIP_RENDERING) ||
1944 ((layer.compositionType == HWC_OVERLAY) &&
1945 ((window_index < 0) || (window_index >= NUM_HW_WINDOWS)))) {
1946 if (layer.acquireFenceFd >= 0)
1947 close(layer.acquireFenceFd);
1948 layer.acquireFenceFd = -1;
1949 layer.releaseFenceFd = -1;
1950
1951 if ((window_index < 0) || (window_index >= NUM_HW_WINDOWS)) {
1952 android::String8 result;
1953 DISPLAY_LOGE("window of layer %d was not assigned (window_index: %d)", i, window_index);
1954 dumpContents(result, contents);
1955 ALOGE(result.string());
1956 result.clear();
1957 dumpLayerInfo(result);
1958 ALOGE(result.string());
1959 }
1960 continue;
1961 }
1962
1963 if ((mVirtualOverlayFlag == true) && (layer.compositionType == HWC_OVERLAY) &&
1964 handle && (getDrmMode(handle->flags) == NO_DRM) &&
1965 (mFirstFb <= i) && (i <= mLastFb))
1966 continue;
1967
1968 if (((layer.compositionType == HWC_OVERLAY) ||
1969 (mFbNeeded == true && layer.compositionType == HWC_FRAMEBUFFER_TARGET))) {
1970 mLastHandles[window_index] = layer.handle;
1971
1972 if (handle && (getDrmMode(handle->flags) == SECURE_DRM))
1973 config[window_index].protection = 1;
1974 else
1975 config[window_index].protection = 0;
1976
1977 if (mLayerInfos[i]->mInternalMPP != NULL) {
1978 mLastMPPMap[window_index].internal_mpp.type = mLayerInfos[i]->mInternalMPP->mType;
1979 mLastMPPMap[window_index].internal_mpp.index = mLayerInfos[i]->mInternalMPP->mIndex;
1980 }
1981 if (mLayerInfos[i]->mExternalMPP != NULL) {
1982 mLastMPPMap[window_index].external_mpp.type = mLayerInfos[i]->mExternalMPP->mType;
1983 mLastMPPMap[window_index].external_mpp.index = mLayerInfos[i]->mExternalMPP->mIndex;
1984 if (postMPPM2M(layer, config, window_index, i) < 0)
1985 continue;
1986 } else {
1987 configureOverlay(&layer, i, config[window_index]);
1988 }
1989 }
1990 if (window_index == 0 && config[window_index].blending != DECON_BLENDING_NONE) {
1991 DISPLAY_LOGD(eDebugWinConfig, "blending not supported on window 0; forcing BLENDING_NONE");
1992 config[window_index].blending = DECON_BLENDING_NONE;
1993 }
1994 if ((window_index < DECON_WIN_UPDATE_IDX) &&
1995 (config[window_index].state != config[window_index].DECON_WIN_STATE_DISABLED) &&
1996 (config[window_index].src.w == 0 || config[window_index].src.h == 0 ||
1997 config[window_index].dst.w == 0 || config[window_index].dst.h == 0)) {
1998 config[window_index].state = config[window_index].DECON_WIN_STATE_DISABLED;
1999 }
2000 }
2001
2002 if (this->mVirtualOverlayFlag) {
2003 handleStaticLayers(contents, *mWinData, tot_ovly_wins);
2004 }
2005
2006 if ((ret = handleWindowUpdate(contents, config)) < 0)
2007 DISPLAY_LOGD(eDebugWindowUpdate, "[WIN_UPDATE] UpdateRegion is FullScreen, ret(%d)", ret);
2008
2009 #if defined(USES_DUAL_DISPLAY)
2010 if (mType == EXYNOS_PRIMARY_DISPLAY) {
2011 int8_t indexLastConfig = 0;
2012 for (size_t i = 0; i < NUM_HW_WINDOWS; i++) {
2013 if (config[i].state == config[i].DECON_WIN_STATE_DISABLED) {
2014 indexLastConfig = i;
2015 break;
2016 }
2017 }
2018 if (mHwc->secondaryDisplay->mEnabled) {
2019 for (size_t i = 0; i < NUM_HW_WINDOWS; i++) {
2020 struct decon_win_config &secondary_config = mHwc->secondaryDisplay->mLastConfigData.config[i];
2021 int8_t index = 0;
2022 if (indexLastConfig == NUM_HW_WINDOWS) {
2023 DISPLAY_LOGE("primaryDisplay last config index is not valid(primaryLastIndex: %d)",
2024 indexLastConfig);
2025 break;
2026 }
2027 if (i == (NUM_HW_WINDOWS - 1))
2028 index = i;
2029 else
2030 index = indexLastConfig + i;
2031 DISPLAY_LOGD(eDebugWinConfig, "secondary_config window %u configuration:", i);
2032 dumpConfig(secondary_config);
2033 if (secondary_config.state != secondary_config.DECON_WIN_STATE_DISABLED) {
2034 if (index >= NUM_HW_WINDOWS) {
2035 DISPLAY_LOGE("secondaryDisplay config index is not valid(primaryLastIndex: %d, index:%d",
2036 indexLastConfig, index);
2037 } else {
2038 memcpy(&config[index],&secondary_config, sizeof(struct decon_win_config));
2039 mLastHandles[index] = mHwc->secondaryDisplay->mLastHandles[i];
2040 }
2041 }
2042 }
2043 }
2044 }
2045
2046 if (mType != EXYNOS_SECONDARY_DISPLAY)
2047 {
2048 #endif
2049 for (size_t i = 0; i <= NUM_HW_WINDOWS; i++) {
2050 DISPLAY_LOGD(eDebugWinConfig, "window %u configuration:", i);
2051 dumpConfig(config[i]);
2052 }
2053
2054 if (checkConfigValidation(config) < 0) {
2055 android::String8 result;
2056 DISPLAY_LOGE("WIN_CONFIG is not valid");
2057 for (size_t i = 0; i <= MAX_DECON_WIN; i++) {
2058 result.appendFormat("window %zu configuration:\n", i);
2059 dumpConfig(config[i], result);
2060 }
2061 ALOGE(result.string());
2062 result.clear();
2063 dumpContents(result, contents);
2064 ALOGE(result.string());
2065 result.clear();
2066 dumpLayerInfo(result);
2067 ALOGE(result.string());
2068 }
2069
2070 if (checkConfigChanged(*mWinData, mLastConfigData) == false) {
2071 ret = 0;
2072 } else {
2073 ret = winconfigIoctl(mWinData);
2074 if (ret < 0) {
2075 DISPLAY_LOGE("ioctl S3CFB_WIN_CONFIG failed: %s", strerror(errno));
2076 } else {
2077 ret = mWinData->fence;
2078 memcpy(&(this->mLastConfigData), mWinData, sizeof(*mWinData));
2079 }
2080 }
2081
2082 /*
2083 * Acquire fence of all of OVERLAY layers(including layers for secondary LCD)
2084 * should be closed even if WIN_CONFIG is skipped
2085 */
2086 for (size_t i = 0; i < NUM_HW_WINDOWS; i++) {
2087 if (config[i].fence_fd != -1)
2088 close(config[i].fence_fd);
2089 }
2090 #if defined(USES_DUAL_DISPLAY)
2091 } else {
2092 memcpy(&(this->mLastConfigData), mWinData, sizeof(*mWinData));
2093 }
2094 #endif
2095 if (contents->numHwLayers == 1) {
2096 hwc_layer_1_t &layer = contents->hwLayers[0];
2097 if (layer.acquireFenceFd >= 0)
2098 close(layer.acquireFenceFd);
2099 layer.acquireFenceFd = -1;
2100 layer.releaseFenceFd = -1;
2101 }
2102 rectCount = 0;
2103 for (size_t i = 0; i < contents->numHwLayers; i++) {
2104 hwc_layer_1_t &layer = contents->hwLayers[i];
2105 if (layer.handle) {
2106 private_handle_t *handle = private_handle_t::dynamicCast(layer.handle);
2107 if (handle->format == HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SP_M_PRIV
2108 && rectCount < mOriginFrect.size())
2109 layer.sourceCropf = mOriginFrect[rectCount++];
2110 }
2111 }
2112 mOriginFrect.clear();
2113 mBackUpFrect.clear();
2114
2115 if (!this->mVirtualOverlayFlag && (ret >= 0))
2116 this->mLastFbWindow = mFbWindow;
2117
2118 return ret;
2119 }
2120
2121 void ExynosDisplay::skipStaticLayers(hwc_display_contents_1_t* contents)
2122 {
2123 mVirtualOverlayFlag = 0;
2124 int win_map = 0;
2125 int fbIndex = contents->numHwLayers - 1;
2126
2127 if (!mHwc->hwc_ctrl.skip_static_layer_mode)
2128 return;
2129
2130 if (mBypassSkipStaticLayer)
2131 return;
2132
2133 if (contents->flags & HWC_GEOMETRY_CHANGED) {
2134 mSkipStaticInitFlag = false;
2135 return;
2136 }
2137
2138 if (!mFbNeeded || ((mLastFb - mFirstFb + 1) > NUM_VIRT_OVER)) {
2139 mSkipStaticInitFlag = false;
2140 return;
2141 }
2142
2143 if (mSkipStaticInitFlag) {
2144 if (mNumStaticLayers != (mLastFb - mFirstFb + 1)) {
2145 mSkipStaticInitFlag = false;
2146 return;
2147 }
2148
2149 for (size_t i = mFirstFb; i <= mLastFb; i++) {
2150 hwc_layer_1_t &layer = contents->hwLayers[i];
2151 if (!layer.handle || (layer.flags & HWC_SKIP_LAYER) || (mLastLayerHandles[i - mFirstFb] != layer.handle)) {
2152 mSkipStaticInitFlag = false;
2153 return;
2154 }
2155 }
2156
2157 if ((mLastFbWindow >= NUM_HW_WINDOWS) || (fbIndex < 0)) {
2158 mSkipStaticInitFlag = false;
2159 DISPLAY_LOGE("skipStaticLayers:: invalid mLastFbWindow(%d), fbIndex(%d)", mLastFbWindow, fbIndex);
2160 return;
2161 }
2162 /* DMA mapping is changed */
2163 if (mLastConfigData.config[mLastFbWindow].idma_type != mLayerInfos[fbIndex]->mDmaType) {
2164 mSkipStaticInitFlag = false;
2165 return;
2166 }
2167
2168 mVirtualOverlayFlag = 1;
2169 for (size_t i = 0; i < contents->numHwLayers-1; i++) {
2170 hwc_layer_1_t &layer = contents->hwLayers[i];
2171 if (layer.compositionType == HWC_FRAMEBUFFER) {
2172 layer.compositionType = HWC_OVERLAY;
2173 mLayerInfos[i]->compositionType = layer.compositionType;
2174 mLayerInfos[i]->mCheckOverlayFlag |= eSkipStaticLayer;
2175 }
2176 }
2177 mLastFbWindow = mFbWindow;
2178 return;
2179 }
2180
2181 mSkipStaticInitFlag = true;
2182 for (size_t i = 0; i < NUM_VIRT_OVER; i++)
2183 mLastLayerHandles[i] = 0;
2184
2185 for (size_t i = mFirstFb; i <= mLastFb; i++) {
2186 hwc_layer_1_t &layer = contents->hwLayers[i];
2187 mLastLayerHandles[i - mFirstFb] = layer.handle;
2188 }
2189 mNumStaticLayers = (mLastFb - mFirstFb + 1);
2190
2191 return;
2192 }
2193
2194 void ExynosDisplay::dumpMPPs(android::String8& result)
2195 {
2196 result.appendFormat("displayType(%d)\n", mType);
2197 result.appendFormat("Internal MPPs number: %zu\n", mInternalMPPs.size());
2198 result.append(
2199 " mType | mIndex | mState \n"
2200 "-------+--------+-----------\n");
2201 // 5____ | 6_____ | 9________ \n
2202
2203 for (size_t i = 0; i < mInternalMPPs.size(); i++) {
2204 ExynosMPPModule* internalMPP = mInternalMPPs[i];
2205 result.appendFormat(" %5d | %6d | %9d \n",
2206 internalMPP->mType, internalMPP->mIndex, internalMPP->mState);
2207 }
2208
2209 result.append("\n");
2210 result.appendFormat("External MPPs number: %zu\n", mExternalMPPs.size());
2211 result.append(
2212 " mType | mIndex | mState \n"
2213 "-------+--------+-----------\n");
2214 // 5____ | 6_____ | 9________ \n
2215
2216 for (size_t i = 0; i < mExternalMPPs.size(); i++) {
2217 ExynosMPPModule* internalMPP = mExternalMPPs[i];
2218 result.appendFormat(" %5d | %6d | %9d \n",
2219 internalMPP->mType, internalMPP->mIndex, internalMPP->mState);
2220 }
2221 }
2222
2223 void ExynosDisplay::preAssignFbTarget(hwc_display_contents_1_t *contents, bool assign)
2224 {
2225 ExynosMPPModule* supportedInternalMPP = NULL;
2226 ExynosMPPModule* supportedExternalMPP = NULL;
2227
2228 int fbIndex = contents->numHwLayers - 1;
2229 hwc_layer_1_t &layer = contents->hwLayers[fbIndex];
2230 mFbPreAssigned = false;
2231
2232 if (!assign)
2233 return;
2234
2235 if (layer.compositionType != HWC_FRAMEBUFFER_TARGET) {
2236 ALOGE("preAssignFbTarget: FRAMEBUFFER_TARGET is not set properly");
2237 return;
2238 }
2239
2240 bool ret = isOverlaySupported(layer, fbIndex, true, &supportedInternalMPP, &supportedExternalMPP);
2241 if (ret && (supportedInternalMPP != NULL) && (supportedExternalMPP == NULL)) {
2242 DISPLAY_LOGD(eDebugResourceAssigning, "Preassigning FramebufferTarget with internalMPP(%d, %d)", supportedInternalMPP->mType, supportedInternalMPP->mIndex);
2243 supportedInternalMPP->mState = MPP_STATE_ASSIGNED;
2244 mLayerInfos[fbIndex]->mInternalMPP = supportedInternalMPP;
2245 mLayerInfos[fbIndex]->mDmaType = getDeconDMAType(mLayerInfos[fbIndex]->mInternalMPP);
2246 for (size_t i = 0; i < mInternalMPPs.size(); i++) {
2247 if ((ExynosMPPModule *)mInternalMPPs[i] == supportedInternalMPP) {
2248 mInternalMPPs.removeItemsAt(i);
2249 }
2250 }
2251 mFbPreAssigned = true;
2252 } else {
2253 ALOGE("preAssignFbTarget: preassigning FB failed");
2254 return;
2255 }
2256 }
2257
2258 void ExynosDisplay::determineYuvOverlay(hwc_display_contents_1_t *contents)
2259 {
2260 mYuvLayers = 0;
2261 bool useVPPOverlayFlag = false, hasDrmLayer = mHasDrmSurface;
2262 uint32_t rectCount = 0;
2263 int drmLayerIndex = mForceOverlayLayerIndex;
2264 size_t i;
2265 mForceOverlayLayerIndex = -1;
2266 mHasDrmSurface = false;
2267
2268 for (size_t j = 0; j < contents->numHwLayers; j++) {
2269 i = hasDrmLayer ? ((j + drmLayerIndex) % contents->numHwLayers) : j;
2270
2271 ExynosMPPModule* supportedInternalMPP = NULL;
2272 ExynosMPPModule* supportedExternalMPP = NULL;
2273 hwc_layer_1_t &layer = contents->hwLayers[i];
2274 useVPPOverlayFlag = false;
2275 hwc_frect_t origin;
2276 if (layer.handle) {
2277 private_handle_t *handle = private_handle_t::dynamicCast(layer.handle);
2278
2279 if (getDrmMode(handle->flags) != NO_DRM) {
2280 useVPPOverlayFlag = true;
2281 if (mHwc->hdmi_hpd && (!mHwc->video_playback_status)) {
2282 layer.flags |= HWC_SKIP_RENDERING;
2283 continue;
2284 } else
2285 layer.flags &= ~HWC_SKIP_RENDERING;
2286 }
2287
2288 /* check yuv surface */
2289 if (!isFormatRgb(handle->format)) {
2290 if (mForceFb && (getDrmMode(handle->flags) == NO_DRM)) {
2291 layer.compositionType = HWC_FRAMEBUFFER;
2292 mLayerInfos[i]->compositionType = layer.compositionType;
2293 mLayerInfos[i]->mCheckOverlayFlag |= eForceFbEnabled;
2294 continue;
2295 }
2296 /* HACK: force integer source crop */
2297 layer.sourceCropf.top = (int)layer.sourceCropf.top;
2298 layer.sourceCropf.left = (int)layer.sourceCropf.left;
2299 layer.sourceCropf.bottom = (int)(layer.sourceCropf.bottom + 0.9);
2300 layer.sourceCropf.right = (int)(layer.sourceCropf.right + 0.9);
2301
2302 /* support to process interlaced color format data */
2303 if (handle->format == HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SP_M_PRIV) {
2304 void *metaData = NULL;
2305 int interlacedType = -1;
2306 mOriginFrect.push(layer.sourceCropf);
2307
2308 if (handle->fd2 >= 0) {
2309 metaData = mmap(0, 64, PROT_READ|PROT_WRITE, MAP_SHARED, handle->fd2, 0);
2310 if (metaData)
2311 interlacedType = *(int *)metaData;
2312 else
2313 interlacedType = -1;
2314 }
2315
2316 if (interlacedType == V4L2_FIELD_INTERLACED_BT) {
2317 if ((int)layer.sourceCropf.left < (int)(handle->stride)) {
2318 layer.sourceCropf.left = (int)layer.sourceCropf.left + handle->stride;
2319 layer.sourceCropf.right = (int)layer.sourceCropf.right + handle->stride;
2320 }
2321 }
2322 if (interlacedType == V4L2_FIELD_INTERLACED_TB || interlacedType == V4L2_FIELD_INTERLACED_BT) {
2323 layer.sourceCropf.top = (int)(layer.sourceCropf.top)/2;
2324 layer.sourceCropf.bottom = (int)(layer.sourceCropf.bottom)/2;
2325 }
2326 mBackUpFrect.push(layer.sourceCropf);
2327
2328 if (metaData)
2329 munmap(metaData, 64);
2330 }
2331
2332 if (isOverlaySupported(contents->hwLayers[i], i, useVPPOverlayFlag, &supportedInternalMPP, &supportedExternalMPP)) {
2333 this->mYuvLayers++;
2334 if (this->mHasDrmSurface == false) {
2335 /* Assign MPP */
2336 if (supportedExternalMPP != NULL)
2337 supportedExternalMPP->mState = MPP_STATE_ASSIGNED;
2338 if (supportedInternalMPP != NULL)
2339 supportedInternalMPP->mState = MPP_STATE_ASSIGNED;
2340
2341 mForceOverlayLayerIndex = i;
2342 layer.compositionType = HWC_OVERLAY;
2343 mLayerInfos[i]->mExternalMPP = supportedExternalMPP;
2344 mLayerInfos[i]->mInternalMPP = supportedInternalMPP;
2345 mLayerInfos[i]->compositionType = layer.compositionType;
2346
2347 if ((getDrmMode(handle->flags) != NO_DRM) &&
2348 isBothMPPProcessingRequired(layer) &&
2349 (supportedInternalMPP != NULL)) {
2350 layer.displayFrame.right = layer.displayFrame.left +
2351 ALIGN_DOWN(WIDTH(layer.displayFrame), supportedInternalMPP->getCropWidthAlign(layer));
2352 layer.displayFrame.bottom = layer.displayFrame.top +
2353 ALIGN_DOWN(HEIGHT(layer.displayFrame), supportedInternalMPP->getCropHeightAlign(layer));
2354 }
2355
2356 if ((getDrmMode(handle->flags) != NO_DRM) &&
2357 (supportedInternalMPP != NULL)) {
2358 if (WIDTH(layer.displayFrame) < supportedInternalMPP->getMinWidth(layer)) {
2359 ALOGE("determineYuvOverlay layer %d displayFrame width %d is smaller than vpp minWidth %d",
2360 i, WIDTH(layer.displayFrame), supportedInternalMPP->getMinWidth(layer));
2361 layer.displayFrame.right = layer.displayFrame.left +
2362 ALIGN_DOWN(WIDTH(layer.displayFrame), supportedInternalMPP->getMinWidth(layer));
2363 }
2364 if (HEIGHT(layer.displayFrame) < supportedInternalMPP->getMinHeight(layer)) {
2365 ALOGE("determineYuvOverlay layer %d displayFrame height %d is smaller than vpp minHeight %d",
2366 i, HEIGHT(layer.displayFrame), supportedInternalMPP->getMinHeight(layer));
2367 layer.displayFrame.bottom = layer.displayFrame.top +
2368 ALIGN_DOWN(HEIGHT(layer.displayFrame), supportedInternalMPP->getMinHeight(layer));
2369 }
2370 }
2371 }
2372 } else {
2373 if (getDrmMode(handle->flags) != NO_DRM) {
2374 /* This layer should be overlay but HWC can't handle it */
2375 layer.compositionType = HWC_OVERLAY;
2376 mLayerInfos[i]->compositionType = layer.compositionType;
2377 layer.flags |= HWC_SKIP_RENDERING;
2378 }
2379 }
2380 }
2381
2382 if (getDrmMode(handle->flags) != NO_DRM) {
2383 this->mHasDrmSurface = true;
2384 mForceOverlayLayerIndex = i;
2385 }
2386 }
2387 if (layer.handle) {
2388 private_handle_t *handle = private_handle_t::dynamicCast(layer.handle);
2389 if (handle->format == HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SP_M_PRIV
2390 && rectCount < mOriginFrect.size())
2391 layer.sourceCropf = mOriginFrect[rectCount++];
2392 }
2393 }
2394 }
2395
2396 void ExynosDisplay::determineSupportedOverlays(hwc_display_contents_1_t *contents)
2397 {
2398 bool videoLayer = false;
2399
2400 mFbNeeded = false;
2401 mFirstFb = ~0;
2402 mLastFb = 0;
2403 uint32_t rectCount = 0;
2404
2405 // find unsupported overlays
2406 for (size_t i = 0; i < contents->numHwLayers; i++) {
2407 hwc_layer_1_t &layer = contents->hwLayers[i];
2408
2409 mLayerInfos[i]->mCompressed = isCompressed(layer);
2410 if (layer.compositionType == HWC_FRAMEBUFFER_TARGET) {
2411 DISPLAY_LOGD(eDebugOverlaySupported, "\tlayer %u: framebuffer target", i);
2412 mLayerInfos[i]->compositionType = layer.compositionType;
2413 continue;
2414 }
2415
2416 if (layer.compositionType == HWC_BACKGROUND && !mForceFb) {
2417 DISPLAY_LOGD(eDebugOverlaySupported, "\tlayer %u: background supported", i);
2418 dumpLayer(eDebugOverlaySupported, &contents->hwLayers[i]);
2419 mLayerInfos[i]->compositionType = layer.compositionType;
2420 continue;
2421 }
2422
2423 if (layer.flags & HWC_SKIP_RENDERING) {
2424 layer.compositionType = HWC_OVERLAY;
2425 mLayerInfos[i]->compositionType = layer.compositionType;
2426 continue;
2427 }
2428
2429 if (layer.handle) {
2430 private_handle_t *handle = private_handle_t::dynamicCast(layer.handle);
2431 if (handle->format == HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SP_M_PRIV
2432 && rectCount < mBackUpFrect.size())
2433 layer.sourceCropf = mBackUpFrect[rectCount++];
2434
2435 ExynosMPPModule* supportedInternalMPP = NULL;
2436 ExynosMPPModule* supportedExternalMPP = NULL;
2437
2438 if ((int)get_yuv_planes(halFormatToV4L2Format(handle->format)) > 0) {
2439 videoLayer = true;
2440 if (!mHwc->hdmi_hpd && mHwc->mS3DMode == S3D_MODE_READY)
2441 mHwc->mS3DMode = S3D_MODE_RUNNING;
2442 }
2443 mHwc->incomingPixels += WIDTH(layer.displayFrame) * HEIGHT(layer.displayFrame);
2444 DISPLAY_LOGD(eDebugOverlaySupported, "\tlayer(%d), type=%d, flags=%08x, handle=%p, tr=%02x, blend=%04x, "
2445 "{%7.1f,%7.1f,%7.1f,%7.1f}, {%d,%d,%d,%d}", i,
2446 layer.compositionType, layer.flags, layer.handle, layer.transform,
2447 layer.blending,
2448 layer.sourceCropf.left,
2449 layer.sourceCropf.top,
2450 layer.sourceCropf.right,
2451 layer.sourceCropf.bottom,
2452 layer.displayFrame.left,
2453 layer.displayFrame.top,
2454 layer.displayFrame.right,
2455 layer.displayFrame.bottom);
2456 /* Video layer's compositionType was set in determineYuvOverlay */
2457 if (!isFormatRgb(handle->format) && layer.compositionType == HWC_OVERLAY)
2458 continue;
2459
2460 if(((getDrmMode(handle->flags) != NO_DRM) ||
2461 (!mForceFb && (!mHwc->hwc_ctrl.dynamic_recomp_mode || mHwc->CompModeSwitch != HWC_2_GLES))) &&
2462 isOverlaySupported(contents->hwLayers[i], i, false, &supportedInternalMPP, &supportedExternalMPP)) {
2463 DISPLAY_LOGD(eDebugOverlaySupported, "\tlayer %u: overlay supported", i);
2464 if (supportedExternalMPP != NULL) {
2465 supportedExternalMPP->mState = MPP_STATE_ASSIGNED;
2466 mLayerInfos[i]->mExternalMPP = supportedExternalMPP;
2467 }
2468 if (supportedInternalMPP != NULL) {
2469 supportedInternalMPP->mState = MPP_STATE_ASSIGNED;
2470 mLayerInfos[i]->mInternalMPP = supportedInternalMPP;
2471 }
2472
2473 layer.compositionType = HWC_OVERLAY;
2474 mLayerInfos[i]->compositionType = layer.compositionType;
2475
2476 dumpLayer(eDebugOverlaySupported, &contents->hwLayers[i]);
2477 continue;
2478 } else {
2479 ExynosMPPModule *dummyInternal = NULL;
2480 ExynosMPPModule *dummyExternal = NULL;
2481 DISPLAY_LOGD(eDebugOverlaySupported, "\tlayer %u: overlay is not supported, dynamic_recomp_mode(%d), CompModeSwitch(%d)", i, mHwc->hwc_ctrl.dynamic_recomp_mode, mHwc->CompModeSwitch);
2482 if (mForceFb)
2483 mLayerInfos[i]->mCheckOverlayFlag |= eForceFbEnabled;
2484 else if (mHwc->hwc_ctrl.dynamic_recomp_mode && mHwc->CompModeSwitch == HWC_2_GLES)
2485 mLayerInfos[i]->mCheckOverlayFlag |= eDynamicRecomposition;
2486 else if (isOverlaySupported(contents->hwLayers[i], i, false, &dummyInternal, &dummyExternal))
2487 mLayerInfos[i]->mCheckOverlayFlag |= eUnknown;
2488 }
2489 } else {
2490 mLayerInfos[i]->mCheckOverlayFlag |= eInvalidHandle;
2491 }
2492
2493 if (!mFbNeeded) {
2494 mFirstFb = i;
2495 mFbNeeded = true;
2496 }
2497 mLastFb = i;
2498 layer.compositionType = HWC_FRAMEBUFFER;
2499 mLayerInfos[i]->compositionType = layer.compositionType;
2500
2501 dumpLayer(eDebugOverlaySupported, &contents->hwLayers[i]);
2502 }
2503
2504 if (!mHwc->hdmi_hpd && mHwc->mS3DMode == S3D_MODE_RUNNING && !videoLayer)
2505 mHwc->mS3DMode = S3D_MODE_DISABLED;
2506 hwc_rect_t base_rect = {0, 0, 0, 0};
2507 hwc_rect_t intersect_rect;
2508 for (size_t i = 0; i < contents->numHwLayers; i++) {
2509 hwc_layer_1_t &layer = contents->hwLayers[i];
2510 if (layer.compositionType == HWC_OVERLAY) {
2511 if (i == 0) {
2512 base_rect = layer.displayFrame;
2513 } else if (hasPlaneAlpha(layer)) {
2514 //if alpha layer is not completely overlapped with base layer, bypass the alpha layer to GLES.
2515 intersect_rect = intersection(base_rect, layer.displayFrame);
2516 if (!rectEqual(intersect_rect, layer.displayFrame)) {
2517 layer.compositionType = HWC_FRAMEBUFFER;
2518 mLayerInfos[i]->compositionType = layer.compositionType;
2519 mLayerInfos[i]->mCheckOverlayFlag |= eUnsupportedBlending;
2520 mFirstFb = min(mFirstFb, i);
2521 mLastFb = max(mLastFb, i);
2522 mFbNeeded = true;
2523 break;
2524 }
2525 }
2526 } else {
2527 // if one of the bottom layer is HWC_FRAMEBUFFER type, no need to force the alpha layer to FRAMEBUFFER type.
2528 break;
2529 }
2530 }
2531 mFirstFb = min(mFirstFb, (size_t)NUM_HW_WINDOWS-1);
2532 // can't composite overlays sandwiched between framebuffers
2533 if (mFbNeeded) {
2534 private_handle_t *handle = NULL;
2535 for (size_t i = mFirstFb; i < mLastFb; i++) {
2536 if (contents->hwLayers[i].flags & HWC_SKIP_RENDERING)
2537 continue;
2538
2539 hwc_layer_1_t &layer = contents->hwLayers[i];
2540 handle = NULL;
2541 if (layer.handle)
2542 handle = private_handle_t::dynamicCast(layer.handle);
2543 if (handle && getDrmMode(handle->flags) != NO_DRM) {
2544 layer.hints = HWC_HINT_CLEAR_FB;
2545 } else {
2546 contents->hwLayers[i].compositionType = HWC_FRAMEBUFFER;
2547 mLayerInfos[i]->compositionType = contents->hwLayers[i].compositionType;
2548 mLayerInfos[i]->mCheckOverlayFlag |= eSandwitchedBetweenGLES;
2549 if (mLayerInfos[i]->mExternalMPP != NULL) {
2550 mLayerInfos[i]->mExternalMPP->mState = MPP_STATE_FREE;
2551 mLayerInfos[i]->mExternalMPP = NULL;
2552 }
2553 if (mLayerInfos[i]->mInternalMPP != NULL) {
2554 mLayerInfos[i]->mInternalMPP->mState = MPP_STATE_FREE;
2555 mLayerInfos[i]->mInternalMPP = NULL;
2556 }
2557 }
2558 }
2559 }
2560 }
2561
2562 void ExynosDisplay::determineBandwidthSupport(hwc_display_contents_1_t *contents)
2563 {
2564 // Incrementally try to add our supported layers to hardware windows.
2565 // If adding a layer would violate a hardware constraint, force it
2566 // into the framebuffer and try again. (Revisiting the entire list is
2567 // necessary because adding a layer to the framebuffer can cause other
2568 // windows to retroactively violate constraints.)
2569 bool changed;
2570 this->mBypassSkipStaticLayer = false;
2571 unsigned int cannotComposeFlag = 0;
2572 int internalDMAsUsed = 0;
2573 int retry = 0;
2574 int fbIndex = contents->numHwLayers - 1;
2575
2576 // Initialize to inverse values so that
2577 // min(left, l) = l, min(top, t) = t
2578 // max(right, r) = r, max(bottom, b) = b
2579 // for all l, t, r, b
2580 mFbUpdateRegion.left = mXres;
2581 mFbUpdateRegion.top = mYres;
2582 mFbUpdateRegion.right = 0;
2583 mFbUpdateRegion.bottom = 0;
2584
2585 do {
2586 uint32_t win_idx = 0;
2587 size_t windows_left;
2588 unsigned int directFbNum = 0;
2589 int videoOverlays = 0;
2590 mHwc->totPixels = 0;
2591 ExynosMPPModule* supportedInternalMPP = NULL;
2592 ExynosMPPModule* supportedExternalMPP = NULL;
2593 bool ret = 0;
2594
2595 for (size_t i = 0; i < mInternalMPPs.size(); i++) {
2596 if (mInternalMPPs[i]->mState != MPP_STATE_TRANSITION &&
2597 (!mHasDrmSurface ||
2598 (mLayerInfos[mForceOverlayLayerIndex]->mInternalMPP != mInternalMPPs[i]))) {
2599 mInternalMPPs[i]->mState = MPP_STATE_FREE;
2600 }
2601 }
2602
2603 for (size_t i = 0; i < mExternalMPPs.size(); i++) {
2604 if (mExternalMPPs[i]->mState != MPP_STATE_TRANSITION &&
2605 (!mHasDrmSurface ||
2606 (mLayerInfos[mForceOverlayLayerIndex]->mExternalMPP != mExternalMPPs[i]))) {
2607 mExternalMPPs[i]->mState = MPP_STATE_FREE;
2608 }
2609 }
2610
2611 for (size_t i = 0; i < contents->numHwLayers; i++) {
2612 if (!mHasDrmSurface || (int)i != mForceOverlayLayerIndex) {
2613 mLayerInfos[i]->mInternalMPP = NULL;
2614 mLayerInfos[i]->mExternalMPP = NULL;
2615 }
2616 }
2617
2618 changed = false;
2619 mMPPLayers = 0;
2620
2621 if (mFbPreAssigned) {
2622 DISPLAY_LOGD(eDebugResourceAssigning, "fb has been pre-assigned already");
2623 windows_left = min(mAllowedOverlays, mHwc->hwc_ctrl.max_num_ovly) - 1;
2624 } else if (mFbNeeded && (contents->numHwLayers - 1 > 0)) {
2625 hwc_layer_1_t &layer = contents->hwLayers[fbIndex];
2626 if (mUseSecureDMA && (mLastFb == (contents->numHwLayers - 2)) && isOverlaySupportedByIDMA(layer, fbIndex)) {
2627 /* FramebufferTarget is the top layer, Secure DMA is used */
2628 windows_left = min(mAllowedOverlays, mHwc->hwc_ctrl.max_num_ovly);
2629 mLayerInfos[contents->numHwLayers - 1]->mDmaType = IDMA_SECURE;
2630 } else if ((mInternalDMAs.size() > 0) && isOverlaySupportedByIDMA(layer, fbIndex)) {
2631 /* Internal DMA is used */
2632 windows_left = min(mAllowedOverlays, mHwc->hwc_ctrl.max_num_ovly) - 1;
2633 mLayerInfos[contents->numHwLayers - 1]->mDmaType = mInternalDMAs[directFbNum];
2634 win_idx = (win_idx == mFirstFb) ? (win_idx + 1) : win_idx;
2635 directFbNum++;
2636 } else {
2637 /* VPP should be used for DMA */
2638 windows_left = min(mAllowedOverlays, mHwc->hwc_ctrl.max_num_ovly) - 1;
2639 ret = isOverlaySupported(layer, fbIndex, true, &supportedInternalMPP, &supportedExternalMPP);
2640 if (ret && (supportedInternalMPP != NULL)) {
2641 DISPLAY_LOGD(eDebugResourceAssigning, "FramebufferTarget internalMPP(%d, %d)", supportedInternalMPP->mType, supportedInternalMPP->mIndex);
2642 supportedInternalMPP->mState = MPP_STATE_ASSIGNED;
2643 mLayerInfos[fbIndex]->mInternalMPP = supportedInternalMPP;
2644 mLayerInfos[fbIndex]->mDmaType = getDeconDMAType(mLayerInfos[fbIndex]->mInternalMPP);
2645 #if defined(MAX_DECON_DMA_TYPE)
2646 if (mLayerInfos[fbIndex]->mDmaType >= MAX_DECON_DMA_TYPE) {
2647 #else
2648 if (mLayerInfos[fbIndex]->mDmaType >= IDMA_MAX) {
2649 #endif
2650 ALOGE("getDeconDMAType with InternalMPP for FramebufferTarget failed (MPP type: %d, MPP index: %d)",
2651 mLayerInfos[fbIndex]->mInternalMPP->mType, mLayerInfos[fbIndex]->mInternalMPP->mIndex);
2652 mLayerInfos[fbIndex]->mDmaType = 0;
2653 }
2654 win_idx = (win_idx == mFirstFb) ? (win_idx + 1) : win_idx;
2655 } else {
2656 ALOGE("VPP should be assigned to FramebufferTarget but it was failed ret(%d)", ret);
2657 }
2658 }
2659 mHwc->totPixels += mXres * mYres;
2660 } else {
2661 windows_left = min(mAllowedOverlays, mHwc->hwc_ctrl.max_num_ovly);
2662 }
2663
2664 DISPLAY_LOGD(eDebugResourceAssigning, "determineBandwidthSupport:: retry(%d), mAllowedOverlays(%d), windows_left(%d), win_idx(%d)",
2665 retry, mAllowedOverlays, windows_left, win_idx);
2666
2667 for (size_t i = 0; i < contents->numHwLayers; i++) {
2668 hwc_layer_1_t &layer = contents->hwLayers[i];
2669 bool isTopLayer = (i == contents->numHwLayers - 2) ? true:false;
2670 private_handle_t *handle = NULL;
2671
2672 if (layer.flags & HWC_SKIP_RENDERING)
2673 continue;
2674
2675 if ((layer.flags & HWC_SKIP_LAYER) ||
2676 (layer.compositionType == HWC_FRAMEBUFFER_TARGET))
2677 continue;
2678
2679 if (!layer.planeAlpha)
2680 continue;
2681
2682 if (layer.handle)
2683 handle = private_handle_t::dynamicCast(layer.handle);
2684 else
2685 continue;
2686
2687 // we've already accounted for the framebuffer above
2688 if (layer.compositionType == HWC_FRAMEBUFFER)
2689 continue;
2690
2691 // only layer 0 can be HWC_BACKGROUND, so we can
2692 // unconditionally allow it without extra checks
2693 if (layer.compositionType == HWC_BACKGROUND) {
2694 windows_left--;
2695 continue;
2696 }
2697
2698 cannotComposeFlag = 0;
2699 bool can_compose = windows_left && (win_idx < NUM_HW_WINDOWS);
2700 if (mUseSecureDMA && !isCompressed(layer) && isTopLayer)
2701 can_compose = true;
2702 else if (windows_left <= 0 || (win_idx >= NUM_HW_WINDOWS))
2703 cannotComposeFlag |= eInsufficientWindow;
2704 if (!isFormatRgb(handle->format) && videoOverlays >= mHwc->hwc_ctrl.num_of_video_ovly) {
2705 can_compose = false;
2706 cannotComposeFlag |= eInsufficientMPP;
2707 }
2708
2709 /* mInternalMPP, mExternalMPP could be set by determineYuvOverlay */
2710 supportedInternalMPP = mLayerInfos[i]->mInternalMPP;
2711 supportedExternalMPP = mLayerInfos[i]->mExternalMPP;
2712
2713 if (can_compose && !isProcessingRequired(layer) && isOverlaySupportedByIDMA(layer, i) &&
2714 (directFbNum < mInternalDMAs.size() || (mUseSecureDMA && isTopLayer))) {
2715 if (directFbNum < mInternalDMAs.size())
2716 directFbNum++;
2717 DISPLAY_LOGD(eDebugResourceAssigning, "layer(%d) is directFB", i);
2718 } else if (can_compose && isOverlaySupported(layer, i,
2719 !isProcessingRequired(layer) |
2720 (directFbNum >= mInternalDMAs.size() && !(mUseSecureDMA && isTopLayer)),
2721 &supportedInternalMPP, &supportedExternalMPP)) {
2722 DISPLAY_LOGD(eDebugResourceAssigning, "layer(%d) is OVERLAY ",i);
2723 if (supportedInternalMPP != NULL) {
2724 DISPLAY_LOGD(eDebugResourceAssigning, "layer(%d) is OVERLAY internalMPP(%d, %d)", i, supportedInternalMPP->mType, supportedInternalMPP->mIndex);
2725 supportedInternalMPP->mState = MPP_STATE_ASSIGNED;
2726 mLayerInfos[i]->mInternalMPP = supportedInternalMPP;
2727 mLayerInfos[i]->mDmaType = getDeconDMAType(mLayerInfos[i]->mInternalMPP);
2728 }
2729 if (supportedExternalMPP != NULL) {
2730 DISPLAY_LOGD(eDebugResourceAssigning, "layer(%d) is OVERLAY externalMPP(%d, %d)", i, supportedExternalMPP->mType, supportedExternalMPP->mIndex);
2731 supportedExternalMPP->mState = MPP_STATE_ASSIGNED;
2732 mLayerInfos[i]->mExternalMPP = supportedExternalMPP;
2733 if ((supportedInternalMPP == NULL) && isOverlaySupportedByIDMA(layer, i) &&
2734 ((directFbNum < mInternalDMAs.size()) || (mUseSecureDMA && isTopLayer))) {
2735 if (directFbNum < mInternalDMAs.size()) {
2736 mLayerInfos[i]->mDmaType = mInternalDMAs[directFbNum];
2737 directFbNum++;
2738 } else {
2739 mLayerInfos[i]->mDmaType = IDMA_SECURE;
2740 }
2741 }
2742 }
2743 mMPPLayers++;
2744 if (!isFormatRgb(handle->format))
2745 videoOverlays++;
2746 } else {
2747 DISPLAY_LOGD(eDebugResourceAssigning, "layer(%d) is changed to FRAMEBUFFER", i);
2748 can_compose = false;
2749 }
2750
2751 if (!can_compose) {
2752 size_t changed_index = i;
2753 hwc_layer_1_t *layer_for_gles = &contents->hwLayers[i];
2754 if (getDrmMode(handle->flags) != NO_DRM) {
2755 int j = 0;
2756 for (j = i - 1; j >= 0 ; j--) {
2757 layer_for_gles = &contents->hwLayers[j];
2758 if (layer_for_gles->compositionType == HWC_OVERLAY) {
2759 changed_index = j;
2760 break;
2761 }
2762 }
2763 if (j < 0) {
2764 mFirstFb = 0;
2765 changed_index = 0;
2766 layer_for_gles = &contents->hwLayers[changed_index];
2767 }
2768 }
2769 layer_for_gles->compositionType = HWC_FRAMEBUFFER;
2770 mLayerInfos[changed_index]->compositionType = layer_for_gles->compositionType;
2771 mLayerInfos[changed_index]->mCheckOverlayFlag |= cannotComposeFlag;
2772 if (mLayerInfos[changed_index]->mInternalMPP != NULL)
2773 mLayerInfos[changed_index]->mInternalMPP->mState = MPP_STATE_FREE;
2774 if (mLayerInfos[changed_index]->mExternalMPP != NULL)
2775 mLayerInfos[changed_index]->mExternalMPP->mState = MPP_STATE_FREE;
2776 mLayerInfos[changed_index]->mInternalMPP = NULL;
2777 mLayerInfos[changed_index]->mExternalMPP = NULL;
2778 if (!mFbNeeded) {
2779 mFirstFb = mLastFb = changed_index;
2780 mFbNeeded = true;
2781 mHwc->totPixels += mXres * mYres;
2782 }
2783 else {
2784 mFirstFb = min(changed_index, mFirstFb);
2785 mLastFb = max(changed_index, mLastFb);
2786 }
2787 changed = true;
2788 mFirstFb = min(mFirstFb, (size_t)NUM_HW_WINDOWS-1);
2789 break;
2790 } else {
2791 mHwc->totPixels += WIDTH(layer.displayFrame) * HEIGHT(layer.displayFrame);
2792 }
2793
2794 if ((mUseSecureDMA == false) || (isTopLayer == false)) {
2795 win_idx++;
2796 /* FB Target is not top layer */
2797 if (mFbNeeded && ((mUseSecureDMA && !isCompressed(layer))|| (mLastFb != (contents->numHwLayers - 2))))
2798 win_idx = (win_idx == mFirstFb) ? (win_idx + 1) : win_idx;
2799 win_idx = min((size_t)win_idx, (size_t)(NUM_HW_WINDOWS - 1));
2800 windows_left--;
2801 }
2802 }
2803
2804 if (changed)
2805 for (size_t i = mFirstFb; i < mLastFb; i++) {
2806 hwc_layer_1_t &layer = contents->hwLayers[i];
2807 private_handle_t *handle = NULL;
2808 if (layer.handle)
2809 handle = private_handle_t::dynamicCast(layer.handle);
2810 if (handle && getDrmMode(handle->flags) != NO_DRM) {
2811 layer.hints = HWC_HINT_CLEAR_FB;
2812 } else {
2813 contents->hwLayers[i].compositionType = HWC_FRAMEBUFFER;
2814 mLayerInfos[i]->compositionType = contents->hwLayers[i].compositionType;
2815 mLayerInfos[i]->mCheckOverlayFlag |= eSandwitchedBetweenGLES;
2816 if (mLayerInfos[i]->mInternalMPP != NULL)
2817 mLayerInfos[i]->mInternalMPP->mState = MPP_STATE_FREE;
2818 if (mLayerInfos[i]->mExternalMPP != NULL)
2819 mLayerInfos[i]->mExternalMPP->mState = MPP_STATE_FREE;
2820 mLayerInfos[i]->mInternalMPP = NULL;
2821 mLayerInfos[i]->mExternalMPP = NULL;
2822 if (handle && !isFormatRgb(handle->format))
2823 videoOverlays--;
2824 }
2825 }
2826 if (handleTotalBandwidthOverload(contents))
2827 changed = true;
2828 retry++;
2829
2830 if (retry > 100) {
2831 DISPLAY_LOGE("%s", "retry 100, can't allocate vpp, dump error state");
2832 android::String8 result;
2833 result.clear();
2834 dumpLayerInfo(result);
2835 DISPLAY_LOGE("%s", result.string());
2836 break;
2837 }
2838 } while(changed);
2839
2840 uint32_t rectCount = 0;
2841 for (size_t i = 0; i < contents->numHwLayers; i++) {
2842 hwc_layer_1_t &layer = contents->hwLayers[i];
2843 if (layer.handle) {
2844 private_handle_t *handle = private_handle_t::dynamicCast(layer.handle);
2845 if (handle->format == HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SP_M_PRIV
2846 && rectCount < mOriginFrect.size())
2847 layer.sourceCropf = mOriginFrect[rectCount++];
2848 }
2849 }
2850
2851 for (size_t i = 0; i < contents->numHwLayers; i++) {
2852 hwc_layer_1_t &layer = contents->hwLayers[i];
2853 if (layer.compositionType == HWC_FRAMEBUFFER)
2854 mFbUpdateRegion = expand(mFbUpdateRegion, layer.displayFrame);
2855 }
2856
2857 for (size_t i = mLastFb + 1; i < contents->numHwLayers; i++) {
2858 hwc_layer_1_t &layer = contents->hwLayers[i];
2859 if (layer.compositionType == HWC_OVERLAY && layer.planeAlpha > 0 && layer.planeAlpha < 255)
2860 mFbUpdateRegion = expand(mFbUpdateRegion, contents->hwLayers[i].displayFrame);
2861 }
2862
2863 int minWidth = 0;
2864 #ifdef USE_DRM_BURST_LEN
2865 if (mHasDrmSurface)
2866 minWidth = DRM_BURSTLEN_BYTES * 8 / formatToBpp(HAL_PIXEL_FORMAT_RGBA_8888);
2867 else
2868 #endif
2869 minWidth = BURSTLEN_BYTES * 8 / formatToBpp(HAL_PIXEL_FORMAT_RGBA_8888);
2870
2871 int w = WIDTH(mFbUpdateRegion);
2872 if (w < minWidth) {
2873 #if defined(USES_DUAL_DISPLAY)
2874 uint32_t maxRightPosition = (mType == EXYNOS_PRIMARY_DISPLAY)?(mXres/2):mXres;
2875 if (mFbUpdateRegion.left + minWidth <= maxRightPosition)
2876 mFbUpdateRegion.right = mFbUpdateRegion.left + minWidth;
2877 else
2878 mFbUpdateRegion.left = mFbUpdateRegion.right - minWidth;
2879 #else
2880 if (mFbUpdateRegion.left + minWidth <= mXres)
2881 mFbUpdateRegion.right = mFbUpdateRegion.left + minWidth;
2882 else
2883 mFbUpdateRegion.left = mFbUpdateRegion.right - minWidth;
2884 #endif
2885 }
2886 }
2887
2888 void ExynosDisplay::assignWindows(hwc_display_contents_1_t *contents)
2889 {
2890 unsigned int nextWindow = 0;
2891 unsigned int directFbNum = 0;
2892 bool isTopLayer = false;
2893
2894 hwc_layer_1_t &fbLayer = contents->hwLayers[contents->numHwLayers - 1];
2895 if (mFbNeeded && (contents->numHwLayers - 1 > 0)) {
2896 /* FramebufferTarget is the top layer */
2897 if (mUseSecureDMA && !isCompressed(fbLayer) && mLastFb == (contents->numHwLayers - 2))
2898 mLayerInfos[contents->numHwLayers - 1]->mDmaType = IDMA_SECURE;
2899 else if (mInternalDMAs.size() > 0 && !isCompressed(fbLayer)) {
2900 mLayerInfos[contents->numHwLayers - 1]->mDmaType = mInternalDMAs[directFbNum];
2901 directFbNum++;
2902 } else {
2903 /* mDmaType was set by determineBandwidthSupport() */
2904 }
2905
2906 DISPLAY_LOGD(eDebugResourceAssigning, "assigning layer %u to DMA %u", contents->numHwLayers - 1, mLayerInfos[contents->numHwLayers - 1]->mDmaType);
2907 }
2908
2909 if (mFbNeeded && mUseSecureDMA && !isCompressed(fbLayer) && (mLastFb == (contents->numHwLayers - 2)))
2910 mFbWindow = NUM_HW_WINDOWS - 1;
2911 else
2912 mFbWindow = NO_FB_NEEDED;
2913
2914 for (size_t i = 0; i < contents->numHwLayers; i++) {
2915 hwc_layer_1_t &layer = contents->hwLayers[i];
2916 mLayerInfos[i]->mWindowIndex = -1;
2917 isTopLayer = (i == contents->numHwLayers - 2) ? true:false;
2918
2919 if (mFbNeeded && (mFbWindow != NUM_HW_WINDOWS - 1)) {
2920 if (i == mLastFb) {
2921 mFbWindow = nextWindow;
2922 nextWindow++;
2923 continue;
2924 }
2925 }
2926
2927 if (layer.flags & HWC_SKIP_RENDERING)
2928 continue;
2929
2930 if (!layer.planeAlpha) {
2931 if (layer.acquireFenceFd >= 0)
2932 close(layer.acquireFenceFd);
2933 layer.acquireFenceFd = -1;
2934 layer.releaseFenceFd = -1;
2935 continue;
2936 }
2937
2938 if (layer.compositionType != HWC_FRAMEBUFFER) {
2939 if (mFbNeeded && (layer.compositionType == HWC_FRAMEBUFFER_TARGET)) {
2940 DISPLAY_LOGD(eDebugResourceAssigning, "assigning framebuffer target %u to window %u", i, nextWindow);
2941 mLayerInfos[i]->mWindowIndex = mFbWindow;
2942 if (mLayerInfos[i]->mInternalMPP != NULL)
2943 mLayerInfos[i]->mInternalMPP->setDisplay(this);
2944 continue;
2945 }
2946 if (layer.compositionType == HWC_OVERLAY) {
2947 if ((!isProcessingRequired(layer) ||
2948 ((mLayerInfos[i]->mInternalMPP == NULL) && (mLayerInfos[i]->mExternalMPP != NULL))) &&
2949 isOverlaySupportedByIDMA(layer, i) && (directFbNum < mInternalDMAs.size() || (mUseSecureDMA && isTopLayer)))
2950 {
2951 if (directFbNum < mInternalDMAs.size()) {
2952 DISPLAY_LOGD(eDebugResourceAssigning, "assigning layer %u to DMA %u", i, mInternalDMAs[directFbNum]);
2953 mLayerInfos[i]->mDmaType = mInternalDMAs[directFbNum];
2954 mLayerInfos[i]->mWindowIndex = nextWindow;
2955 directFbNum++;
2956 } else {
2957 DISPLAY_LOGD(eDebugResourceAssigning, "assigning layer %u to DMA %u", i, IDMA_SECURE);
2958 mLayerInfos[i]->mDmaType = IDMA_SECURE;
2959 mLayerInfos[i]->mWindowIndex = NUM_HW_WINDOWS - 1;
2960 }
2961 } else {
2962 DISPLAY_LOGD(eDebugResourceAssigning, "%u layer can't use internalDMA, isProcessingRequired(%d)", i, isProcessingRequired(layer));
2963 unsigned int dmaType = 0;
2964 mLayerInfos[i]->mWindowIndex = nextWindow;
2965 if (mLayerInfos[i]->mInternalMPP != NULL) {
2966 mLayerInfos[i]->mInternalMPP->setDisplay(this);
2967 mLayerInfos[i]->mDmaType = getDeconDMAType(mLayerInfos[i]->mInternalMPP);
2968 DISPLAY_LOGD(eDebugResourceAssigning, "assigning layer %u to DMA %u", i, mLayerInfos[i]->mDmaType);
2969 } else {
2970 /* Find unused DMA connected with VPP */
2971 for (size_t j = 0; j < mInternalMPPs.size(); j++ )
2972 {
2973 if ((mInternalMPPs[j]->mState == MPP_STATE_FREE) &&
2974 ((mInternalMPPs[j]->mDisplay == NULL) || (mInternalMPPs[j]->mDisplay == this))) {
2975 mLayerInfos[i]->mInternalMPP = mInternalMPPs[j];
2976 mLayerInfos[i]->mDmaType = getDeconDMAType(mLayerInfos[i]->mInternalMPP);
2977 mLayerInfos[i]->mInternalMPP->setDisplay(this);
2978 mLayerInfos[i]->mInternalMPP->mState = MPP_STATE_ASSIGNED;
2979 DISPLAY_LOGD(eDebugResourceAssigning, "assigning layer %u to DMA %u", i, mLayerInfos[i]->mDmaType);
2980 break;
2981 }
2982 }
2983 }
2984 }
2985 if (mLayerInfos[i]->mExternalMPP != NULL)
2986 mLayerInfos[i]->mExternalMPP->setDisplay(this);
2987 }
2988 if (mLayerInfos[i]->mWindowIndex != NUM_HW_WINDOWS - 1)
2989 nextWindow++;
2990 }
2991 }
2992
2993 for (size_t i = 0; i < contents->numHwLayers; i++) {
2994 hwc_layer_1_t &layer = contents->hwLayers[i];
2995 if (layer.compositionType == HWC_FRAMEBUFFER ||
2996 layer.compositionType == HWC_FRAMEBUFFER_TARGET) {
2997 mLayerInfos[i]->mWindowIndex = mFbWindow;
2998 if (contents->numHwLayers - 1 > 0) {
2999 mLayerInfos[i]->mDmaType = mLayerInfos[contents->numHwLayers - 1]->mDmaType;
3000 }
3001 }
3002 }
3003 }
3004
3005 int ExynosDisplay::postMPPM2M(hwc_layer_1_t &layer, struct decon_win_config *config, int win_map, int index)
3006 {
3007 //exynos5_hwc_post_data_t *pdata = &mPostData;
3008 //int gsc_idx = pdata->gsc_map[index].idx;
3009 int dst_format = mExternalMPPDstFormat;
3010 private_handle_t *handle = private_handle_t::dynamicCast(layer.handle);
3011 ExynosMPPModule *exynosMPP = mLayerInfos[index]->mExternalMPP;
3012 ExynosMPPModule *exynosInternalMPP = mLayerInfos[index]->mInternalMPP;
3013 hwc_layer_1_t extMPPOutLayer;
3014
3015 if (exynosMPP == NULL) {
3016 DISPLAY_LOGE("postMPPM2M is called but externMPP is NULL");
3017 if (layer.acquireFenceFd >= 0)
3018 close(layer.acquireFenceFd);
3019 layer.acquireFenceFd = -1;
3020 layer.releaseFenceFd = -1;
3021 return -1;
3022 }
3023
3024 hwc_frect_t sourceCrop = { 0, 0,
3025 (float)WIDTH(layer.displayFrame), (float)HEIGHT(layer.displayFrame) };
3026 int originalTransform = layer.transform;
3027 hwc_rect_t originalDisplayFrame = layer.displayFrame;
3028
3029 bool bothMPPUsed = isBothMPPProcessingRequired(layer, &extMPPOutLayer);
3030 if (bothMPPUsed) {
3031 sourceCrop.right = extMPPOutLayer.displayFrame.right;
3032 sourceCrop.bottom = extMPPOutLayer.displayFrame.bottom;
3033 layer.displayFrame = extMPPOutLayer.displayFrame;
3034 }
3035
3036 if (mType == EXYNOS_PRIMARY_DISPLAY) {
3037 handle->flags &= ~GRALLOC_USAGE_VIDEO_EXT;
3038 if (mHwc->mS3DMode == S3D_MODE_READY || mHwc->mS3DMode == S3D_MODE_RUNNING) {
3039 int S3DFormat = getS3DFormat(mHwc->mHdmiPreset);
3040 if (S3DFormat == S3D_SBS)
3041 exynosMPP->mS3DMode = S3D_SBS;
3042 else if (S3DFormat == S3D_TB)
3043 exynosMPP->mS3DMode = S3D_TB;
3044 } else {
3045 exynosMPP->mS3DMode = S3D_NONE;
3046 }
3047 }
3048
3049 /* OFF_Screen to ON_Screen changes */
3050 if (getDrmMode(handle->flags) != NO_DRM)
3051 recalculateDisplayFrame(layer, mXres, mYres);
3052
3053 if (mType != EXYNOS_VIRTUAL_DISPLAY &&
3054 (isFormatRgb(handle->format) ||
3055 (bothMPPUsed && !isFormatRgb(handle->format) &&
3056 exynosInternalMPP != NULL &&
3057 exynosInternalMPP->isCSCSupportedByMPP(handle->format, HAL_PIXEL_FORMAT_RGBX_8888, layer.dataSpace) &&
3058 exynosInternalMPP->isFormatSupportedByMPP(handle->format) &&
3059 WIDTH(extMPPOutLayer.displayFrame) % exynosInternalMPP->getCropWidthAlign(layer) == 0 &&
3060 HEIGHT(extMPPOutLayer.displayFrame) % exynosInternalMPP->getCropHeightAlign(layer) == 0)))
3061 dst_format = handle->format;
3062 int err = exynosMPP->processM2M(layer, dst_format, &sourceCrop);
3063
3064 /* Restore displayFrame*/
3065 layer.displayFrame = originalDisplayFrame;
3066
3067 if (err < 0) {
3068 DISPLAY_LOGE("failed to configure MPP (type:%u, index:%u) for layer %u",
3069 exynosMPP->mType, exynosMPP->mIndex, index);
3070 return -1;
3071 }
3072
3073 buffer_handle_t dst_buf = exynosMPP->mDstBuffers[exynosMPP->mCurrentBuf];
3074 private_handle_t *dst_handle =
3075 private_handle_t::dynamicCast(dst_buf);
3076 int fence = exynosMPP->mDstConfig.releaseFenceFd;
3077 hwc_frect originalCrop = layer.sourceCropf;
3078 int originalFormat = handle->format;
3079
3080 /* ExtMPP out is the input of Decon
3081 * and Trsform was processed by ExtMPP
3082 */
3083 layer.sourceCropf = sourceCrop;
3084 layer.transform = 0;
3085 handle->format = dst_format;
3086 configureHandle(dst_handle, index, layer, fence, config[win_map]);
3087
3088 /* Restore sourceCropf and transform */
3089 layer.sourceCropf = originalCrop;
3090 layer.transform = originalTransform;
3091 handle->format = originalFormat;
3092 return 0;
3093 }
3094
3095 void ExynosDisplay::handleStaticLayers(hwc_display_contents_1_t *contents, struct decon_win_config_data &win_data, int __unused tot_ovly_wins)
3096 {
3097 int win_map = 0;
3098 if (mLastFbWindow >= NUM_HW_WINDOWS) {
3099 DISPLAY_LOGE("handleStaticLayers:: invalid mLastFbWindow(%d)", mLastFbWindow);
3100 return;
3101 }
3102 win_map = mLastFbWindow;
3103 DISPLAY_LOGD(eDebugSkipStaicLayer, "[USE] SKIP_STATIC_LAYER_COMP, mLastFbWindow(%d), win_map(%d)\n", mLastFbWindow, win_map);
3104
3105 memcpy(&win_data.config[win_map],
3106 &mLastConfigData.config[win_map], sizeof(struct decon_win_config));
3107 win_data.config[win_map].fence_fd = -1;
3108
3109 for (size_t i = mFirstFb; i <= mLastFb; i++) {
3110 hwc_layer_1_t &layer = contents->hwLayers[i];
3111 private_handle_t *handle = NULL;
3112 if (layer.handle == NULL)
3113 continue;
3114 else
3115 handle = private_handle_t::dynamicCast(layer.handle);
3116
3117 if ((getDrmMode(handle->flags) == NO_DRM) &&
3118 (layer.compositionType == HWC_OVERLAY)) {
3119 DISPLAY_LOGD(eDebugSkipStaicLayer, "[SKIP_STATIC_LAYER_COMP] layer.handle: 0x%p, layer.acquireFenceFd: %d\n", layer.handle, layer.acquireFenceFd);
3120 if (layer.acquireFenceFd >= 0)
3121 close(layer.acquireFenceFd);
3122 layer.acquireFenceFd = -1;
3123 layer.releaseFenceFd = -1;
3124 }
3125 }
3126 }
3127
3128 bool ExynosDisplay::multipleRGBScaling(int format)
3129 {
3130 return isFormatRgb(format) &&
3131 mMPPLayers >= 1;
3132 }
3133
3134 bool ExynosDisplay::isProcessingRequired(hwc_layer_1_t &layer)
3135 {
3136 if (!layer.handle)
3137 return false;
3138 private_handle_t *handle = private_handle_t::dynamicCast(layer.handle);
3139 return !(isFormatRgb(handle->format)) || isScaled(layer) || isTransformed(layer) || isCompressed(layer) ||
3140 isFloat(layer.sourceCropf.left) || isFloat(layer.sourceCropf.top) ||
3141 isFloat(layer.sourceCropf.right - layer.sourceCropf.left) ||
3142 isFloat(layer.sourceCropf.bottom - layer.sourceCropf.top);
3143 }
3144
3145 bool ExynosDisplay::isBothMPPProcessingRequired(hwc_layer_1_t &layer)
3146 {
3147 bool needDoubleOperation = false;
3148 private_handle_t *srcHandle = NULL;
3149
3150 if (layer.handle == NULL)
3151 return false;
3152
3153 srcHandle = private_handle_t::dynamicCast(layer.handle);
3154 if ((mExternalMPPs.size() == 0) || (mInternalMPPs.size() == 0))
3155 return false;
3156
3157 /* Check scale ratio */
3158 int maxUpscaleExt = mExternalMPPs[0]->getMaxUpscale();
3159 int maxUpscaleInt = mCheckIntMPP->getMaxUpscale();
3160 bool rot90or270 = !!(layer.transform & HAL_TRANSFORM_ROT_90);
3161 int srcW = WIDTH(layer.sourceCropf), srcH = HEIGHT(layer.sourceCropf);
3162 int dstW, dstH;
3163 if (rot90or270) {
3164 dstW = HEIGHT(layer.displayFrame);
3165 dstH = WIDTH(layer.displayFrame);
3166 } else {
3167 dstW = WIDTH(layer.displayFrame);
3168 dstH = HEIGHT(layer.displayFrame);
3169 }
3170 needDoubleOperation = ((dstW > srcW * maxUpscaleExt) && (dstW <= srcW * maxUpscaleExt * maxUpscaleInt)) ||
3171 ((dstH > srcH * maxUpscaleExt) && (dstH <= srcH * maxUpscaleExt * maxUpscaleInt));
3172
3173 int maxDownscaleExt = mExternalMPPs[0]->getMaxDownscale(layer);
3174 int maxDownscaleInt = mCheckIntMPP->getMaxDownscale(layer);
3175
3176 needDoubleOperation |= ((dstW < srcW / maxDownscaleExt) && (dstW >= srcW / (maxDownscaleExt * maxDownscaleExt))) ||
3177 ((dstH < srcH / maxDownscaleExt) && (dstH >= srcH / (maxDownscaleExt * maxDownscaleExt)));
3178
3179 /*
3180 * Both VPP and MSC should be used if
3181 * MSC should be used for DRM contents
3182 */
3183 if (getDrmMode(srcHandle->flags) != NO_DRM) {
3184 bool supportVPP = false;
3185 for (size_t i = 0; i < mInternalMPPs.size(); i++ )
3186 {
3187 if (mInternalMPPs[i]->isProcessingSupported(layer, srcHandle->format) > 0) {
3188 supportVPP = true;
3189 break;
3190 }
3191 }
3192 if (supportVPP == false)
3193 needDoubleOperation |= true;
3194 }
3195
3196 /*
3197 * UHD case
3198 * Destination format should be RGB if dstW or dstH is not aligned.
3199 * VPP is not required at this time.
3200 */
3201 if (!isFormatRgb(srcHandle->format) &&
3202 (srcW >= UHD_WIDTH || srcH >= UHD_HEIGHT) &&
3203 (mInternalMPPs.size() > 0) &&
3204 (dstW % mCheckIntMPP->getCropWidthAlign(layer) == 0) &&
3205 (dstH % mCheckIntMPP->getCropHeightAlign(layer) == 0)) {
3206 needDoubleOperation |= true;
3207 }
3208
3209 return needDoubleOperation;
3210 }
3211
3212 bool ExynosDisplay::isBothMPPProcessingRequired(hwc_layer_1_t &layer, hwc_layer_1_t *extMPPOutLayer)
3213 {
3214 bool needDoubleOperation = false;
3215 if (layer.handle == NULL)
3216 return false;
3217
3218 private_handle_t *srcHandle = private_handle_t::dynamicCast(layer.handle);
3219 if ((mExternalMPPs.size() == 0) || (mInternalMPPs.size() == 0))
3220 return false;
3221
3222 int maxUpscaleExt = mExternalMPPs[0]->getMaxUpscale();
3223 int maxUpscaleInt = mCheckIntMPP->getMaxUpscale();
3224 bool rot90or270 = !!(layer.transform & HAL_TRANSFORM_ROT_90);
3225 int srcW = WIDTH(layer.sourceCropf), srcH = HEIGHT(layer.sourceCropf);
3226 int dstW, dstH;
3227 if (rot90or270) {
3228 dstW = HEIGHT(layer.displayFrame);
3229 dstH = WIDTH(layer.displayFrame);
3230 } else {
3231 dstW = WIDTH(layer.displayFrame);
3232 dstH = HEIGHT(layer.displayFrame);
3233 }
3234
3235 int maxDownscaleExt = mExternalMPPs[0]->getMaxDownscale(layer);
3236 int maxDownscaleInt = mCheckIntMPP->getMaxDownscale(layer);
3237
3238 needDoubleOperation = isBothMPPProcessingRequired(layer);
3239
3240 /* set extMPPOutLayer */
3241 if (needDoubleOperation && extMPPOutLayer != NULL) {
3242 memcpy(extMPPOutLayer, &layer, sizeof(hwc_layer_1_t));
3243 extMPPOutLayer->displayFrame.left = 0;
3244 extMPPOutLayer->displayFrame.top = 0;
3245
3246 if (dstW > srcW * maxUpscaleExt) {
3247 extMPPOutLayer->displayFrame.right = ALIGN_UP((int)ceilf((float)dstW/ maxUpscaleInt),
3248 mExternalMPPs[0]->getDstWidthAlign(srcHandle->format));
3249 } else if (dstW < srcW / maxDownscaleExt) {
3250 extMPPOutLayer->displayFrame.right = ALIGN(dstW * maxDownscaleInt,
3251 mExternalMPPs[0]->getDstWidthAlign(srcHandle->format));
3252 } else {
3253 extMPPOutLayer->displayFrame.right = dstW;
3254 }
3255
3256 if (dstH > srcH * maxUpscaleExt) {
3257 extMPPOutLayer->displayFrame.bottom = ALIGN_UP((int)ceilf((float)dstH/ maxUpscaleInt),
3258 mExternalMPPs[0]->getDstHeightAlign(srcHandle->format));
3259 } else if (dstH < srcH / maxDownscaleExt) {
3260 extMPPOutLayer->displayFrame.bottom = ALIGN(dstH * maxDownscaleInt,
3261 mExternalMPPs[0]->getDstHeightAlign(srcHandle->format));
3262 } else {
3263 extMPPOutLayer->displayFrame.bottom = dstH;
3264 }
3265
3266 if (rot90or270) {
3267 dstW = extMPPOutLayer->displayFrame.bottom;
3268 dstH = extMPPOutLayer->displayFrame.right;
3269 extMPPOutLayer->displayFrame.right = dstW;
3270 extMPPOutLayer->displayFrame.bottom = dstH;
3271 }
3272 }
3273
3274 return needDoubleOperation;
3275 }
3276
3277 bool ExynosDisplay::isSourceCropfSupported(hwc_layer_1_t layer)
3278 {
3279 private_handle_t *handle = private_handle_t::dynamicCast(layer.handle);
3280 unsigned int bpp = formatToBpp(handle->format);
3281
3282 /* HACK: Disable overlay if the layer have float position or size */
3283 #if 0
3284 if ((isFormatRgb(handle->format) && (bpp == 32)) ||
3285 isFormatYUV420(handle->format))
3286 return true;
3287 #endif
3288
3289 return false;
3290 }
3291
3292 bool ExynosDisplay::checkConfigChanged(struct decon_win_config_data &lastConfigData, struct decon_win_config_data &newConfigData)
3293 {
3294 for (size_t i = 0; i <= MAX_DECON_WIN; i++) {
3295 if ((lastConfigData.config[i].state != newConfigData.config[i].state) ||
3296 (lastConfigData.config[i].fd_idma[0] != newConfigData.config[i].fd_idma[0]) ||
3297 (lastConfigData.config[i].fd_idma[1] != newConfigData.config[i].fd_idma[1]) ||
3298 (lastConfigData.config[i].fd_idma[2] != newConfigData.config[i].fd_idma[2]) ||
3299 (lastConfigData.config[i].dst.x != newConfigData.config[i].dst.x) ||
3300 (lastConfigData.config[i].dst.y != newConfigData.config[i].dst.y) ||
3301 (lastConfigData.config[i].dst.w != newConfigData.config[i].dst.w) ||
3302 (lastConfigData.config[i].dst.h != newConfigData.config[i].dst.h) ||
3303 (lastConfigData.config[i].src.x != newConfigData.config[i].src.x) ||
3304 (lastConfigData.config[i].src.y != newConfigData.config[i].src.y) ||
3305 (lastConfigData.config[i].src.w != newConfigData.config[i].src.w) ||
3306 (lastConfigData.config[i].src.h != newConfigData.config[i].src.h) ||
3307 (lastConfigData.config[i].format != newConfigData.config[i].format) ||
3308 (lastConfigData.config[i].blending != newConfigData.config[i].blending) ||
3309 (lastConfigData.config[i].plane_alpha != newConfigData.config[i].plane_alpha))
3310 return true;
3311 }
3312 return false;
3313 }
3314
3315 void ExynosDisplay::removeIDMA(decon_idma_type idma)
3316 {
3317 for (size_t i = mInternalDMAs.size(); i-- > 0;) {
3318 if (mInternalDMAs[i] == (unsigned int)idma) {
3319 mInternalDMAs.removeItemsAt(i);
3320 }
3321 }
3322 }
3323
3324 int ExynosDisplay::getDisplayConfigs(uint32_t *configs, size_t *numConfigs)
3325 {
3326 configs[0] = 0;
3327 *numConfigs = 1;
3328 return 0;
3329 }
3330
3331 int ExynosDisplay::getDeconDMAType(ExynosMPPModule* internalMPP)
3332 {
3333 if (internalMPP->mType == MPP_VG)
3334 return IDMA_VG0 + internalMPP->mIndex;
3335 else if (internalMPP->mType == MPP_VGR)
3336 return IDMA_VGR0 + internalMPP->mIndex;
3337 else if (internalMPP->mType == MPP_VPP_G) {
3338 switch (internalMPP->mIndex) {
3339 case 0:
3340 return IDMA_G0;
3341 case 1:
3342 return IDMA_G1;
3343 case 2:
3344 return IDMA_G2;
3345 case 3:
3346 return IDMA_G3;
3347 default:
3348 return -1;
3349 }
3350 } else
3351 return -1;
3352 }
3353
3354 void ExynosDisplay::dumpContents(android::String8& result, hwc_display_contents_1_t *contents)
3355 {
3356 for (size_t i = 0; i < contents->numHwLayers; i++) {
3357 hwc_layer_1_t &layer = contents->hwLayers[i];
3358 result.appendFormat("[%zu] type=%d, flags=%08x, handle=%p, tr=%02x, blend=%04x, "
3359 "{%7.1f,%7.1f,%7.1f,%7.1f}, {%d,%d,%d,%d}\n",
3360 i,
3361 layer.compositionType, layer.flags, layer.handle, layer.transform,
3362 layer.blending,
3363 layer.sourceCropf.left,
3364 layer.sourceCropf.top,
3365 layer.sourceCropf.right,
3366 layer.sourceCropf.bottom,
3367 layer.displayFrame.left,
3368 layer.displayFrame.top,
3369 layer.displayFrame.right,
3370 layer.displayFrame.bottom);
3371
3372 }
3373 }
3374
3375 int ExynosDisplay::checkConfigValidation(decon_win_config *config)
3376 {
3377 bool flagValidConfig = true;
3378 for (size_t i = 0; i < MAX_DECON_WIN; i++) {
3379 if (config[i].state != config[i].DECON_WIN_STATE_DISABLED) {
3380 /* multiple dma mapping */
3381 for (size_t j = (i+1); j < MAX_DECON_WIN; j++) {
3382 if ((config[i].state == config[i].DECON_WIN_STATE_BUFFER) &&
3383 (config[j].state == config[j].DECON_WIN_STATE_BUFFER)) {
3384 if (config[i].idma_type == config[j].idma_type) {
3385 ALOGE("WIN_CONFIG error: duplicated dma(%d) between win%d, win%d",
3386 config[i].idma_type, i, j);
3387 config[j].state = config[j].DECON_WIN_STATE_DISABLED;
3388 flagValidConfig = false;
3389 }
3390 }
3391 }
3392 if ((config[i].src.x < 0) || (config[i].src.y < 0)||
3393 (config[i].dst.x < 0) || (config[i].dst.y < 0)||
3394 (config[i].dst.x + config[i].dst.w > (uint32_t)mXres) ||
3395 (config[i].dst.y + config[i].dst.h > (uint32_t)mYres)) {
3396 ALOGE("WIN_CONFIG error: invalid pos or size win%d", i);
3397 config[i].state = config[i].DECON_WIN_STATE_DISABLED;
3398 flagValidConfig = false;
3399 }
3400
3401 if (i >= NUM_HW_WINDOWS) {
3402 ALOGE("WIN_CONFIG error: invalid window number win%d", i);
3403 config[i].state = config[i].DECON_WIN_STATE_DISABLED;
3404 flagValidConfig = false;
3405 }
3406 }
3407 }
3408
3409 if (flagValidConfig)
3410 return 0;
3411 else
3412 return -1;
3413 }
3414
3415 int ExynosDisplay::setPowerMode(int mode)
3416 {
3417 #if defined(S3CFB_POWER_MODE)
3418 return ioctl(this->mDisplayFd, S3CFB_POWER_MODE, &mode);
3419 #else
3420 return ioctl(this->mDisplayFd, FBIOBLANK, (mode == HWC_POWER_MODE_OFF ? FB_BLANK_POWERDOWN : FB_BLANK_UNBLANK));
3421 #endif
3422 }