lib[vpp]display: Enable window update by default
[GitHub/LineageOS/android_hardware_samsung_slsi_exynos.git] / libdisplay / ExynosOverlayDisplay.cpp
CommitLineData
5763fb39
T
1#define ATRACE_TAG ATRACE_TAG_GRAPHICS
2#include "ExynosOverlayDisplay.h"
3#include "ExynosHWCUtils.h"
4#include "ExynosMPPModule.h"
5#include <utils/Trace.h>
6
7#ifdef G2D_COMPOSITION
8#include "ExynosG2DWrapper.h"
9#endif
10
11ExynosOverlayDisplay::ExynosOverlayDisplay(int numMPPs, struct exynos5_hwc_composer_device_1_t *pdev)
12 : ExynosDisplay(numMPPs),
13 mLastFbWindow(NO_FB_NEEDED),
14 mGrallocModule(NULL),
15 mLastOverlayWindowIndex(-1),
16 mLastOverlayLayerIndex(-1),
17 mVirtualOverlayFlag(0),
18 mForceFbYuvLayer(0),
19 mCountSameConfig(0),
20 mConfigMode(0),
21 mGscLayers(0),
22 mPopupPlayYuvContents(false),
23 mHasCropSurface(false),
24 mYuvLayers(0),
25 mBypassSkipStaticLayer(false),
26 mGscUsed(false),
27 mCurrentGscIndex(0),
28 mFbNeeded(false),
29 mFirstFb(0),
30 mLastFb(0),
31 mForceFb(false),
32 mForceOverlayLayerIndex(-1),
33 mRetry(false),
34 mBlanked(true),
35 mMaxWindowOverlapCnt(NUM_HW_WINDOWS),
36 mAllowedOverlays(5)
37{
38 mMPPs = new ExynosMPPModule*[mNumMPPs];
39 for (int i = 0; i < mNumMPPs; i++)
40 mMPPs[i] = new ExynosMPPModule(this, i);
41
42 for (size_t i = 0; i < MAX_NUM_FIMD_DMA_CH; i++) {
43 mDmaChannelMaxBandwidth[i] = 2560 * 1600;
44 mDmaChannelMaxOverlapCount[i] = 1;
45 }
46
47 memset(&mPostData, 0, sizeof(mPostData));
48 memset(&mLastConfigData, 0, sizeof(mLastConfigData));
49 memset(mLastGscMap, 0, sizeof(mLastGscMap));
50 memset(mLastHandles, 0, sizeof(mLastHandles));
51 memset(mLastLayerHandles, 0, sizeof(mLastLayerHandles));
52 memset(mPrevDstConfig, 0, sizeof(mPrevDstConfig));
53
54 mCurrentRGBMPPIndex = 0;
55 memset(&mFbUpdateRegion, 0, sizeof(mFbUpdateRegion));
56
57 mOtfMode = OTF_OFF;
58 this->mHwc = pdev;
59}
60
61ExynosOverlayDisplay::~ExynosOverlayDisplay()
62{
63 for (int i = 0; i < mNumMPPs; i++)
64 delete mMPPs[i];
65 delete[] mMPPs;
66}
67
68bool ExynosOverlayDisplay::isOverlaySupported(hwc_layer_1_t &layer, size_t i)
69{
70 int mMPPIndex = 0;
71 int ret = 0;
72
73 if (layer.flags & HWC_SKIP_LAYER) {
74 mLayerInfos[i]->mCheckOverlayFlag |= eSkipLayer;
75 ALOGV("\tlayer %u: skipping", i);
76 return false;
77 }
78
79 if (!layer.planeAlpha)
80 return true;
81
82 if (i == 0 && layer.planeAlpha < 255) {
83 mLayerInfos[i]->mCheckOverlayFlag |= eUnsupportedPlaneAlpha;
84 return false;
85 }
86
87 private_handle_t *handle = private_handle_t::dynamicCast(layer.handle);
88
89 if (!handle) {
90 ALOGV("\tlayer %u: handle is NULL", i);
91 mLayerInfos[i]->mCheckOverlayFlag |= eInvalidHandle;
92 return false;
93 }
94
95 if (isFormatRgb(handle->format) && handle->stride >= MAX_BUF_STRIDE) {
96 mLayerInfos[i]->mCheckOverlayFlag |= eExceedHStrideMaximum;
97 return false;
98 }
99
100 mMPPIndex = getMPPForUHD(layer);
101 if (isFormatRgb(handle->format))
102 mMPPIndex = getRGBMPPIndex(0);
103
104 if (!(mMPPs[mMPPIndex]->formatRequiresGsc(handle->format)) &&
105 (formatToBpp(handle->format) == 16) && ((layer.displayFrame.left % 2 != 0) || (layer.displayFrame.right % 2 != 0)))
106 return false;
107
108 if (isSrcCropFloat(layer.sourceCropf) &&
109 getDrmMode(handle->flags) == NO_DRM) {
110 ALOGV("\tlayer %u: has floating crop info [%7.1f %7.1f %7.1f %7.1f]", i,
111 layer.sourceCropf.left, layer.sourceCropf.top, layer.sourceCropf.right,
112 layer.sourceCropf.bottom);
113 mLayerInfos[i]->mCheckOverlayFlag |= eHasFloatSrcCrop;
114 return false;
115 }
116
117 if (visibleWidth(mMPPs[mMPPIndex], layer, handle->format, this->mXres) < BURSTLEN_BYTES) {
118 ALOGV("\tlayer %u: visible area is too narrow", i);
119 mLayerInfos[i]->mCheckOverlayFlag |= eUnsupportedDstWidth;
120 return false;
121 }
122
123 if (mMPPs[mMPPIndex]->isProcessingRequired(layer, handle->format)) {
124 int downNumerator, downDenominator;
125 int downError = mMPPs[mMPPIndex]->getDownscaleRatio(&downNumerator, &downDenominator);
126 /* Check whether GSC can handle using local or M2M */
127 ret = mMPPs[mMPPIndex]->isProcessingSupported(layer, handle->format, false);
128 if (ret < 0) {
129 ALOGV("\tlayer %u: MPP M2M required but not supported", i);
130 mLayerInfos[i]->mCheckOverlayFlag |= eMPPUnsupported;
131 mLayerInfos[i]->mCheckMPPFlag |= -ret;
132
133 ret = mMPPs[mMPPIndex]->isProcessingSupported(layer, handle->format, true, downNumerator, downDenominator);
134 if (ret < 0) {
135 ALOGV("\tlayer %u: MPP OTF required but not supported", i);
136 mLayerInfos[i]->mCheckOverlayFlag |= eMPPUnsupported;
137 mLayerInfos[i]->mCheckMPPFlag |= -ret;
138 return false;
139 }
140 }
141 } else {
142#ifdef USE_FB_PHY_LINEAR
143#ifdef G2D_COMPOSITION
144 if ((this->mG2dComposition) && (this->mG2dLayers < (int)(NUM_HW_WIN_FB_PHY - 1)))
145 this->mG2d.ovly_lay_idx[this->mG2dLayers++] = i;
146 else
147#endif
148 return false;
149#endif
150 if (!isFormatSupported(handle->format)) {
151 mLayerInfos[i]->mCheckOverlayFlag |= eUnsupportedFormat;
152 ALOGV("\tlayer %u: pixel format %u not supported", i, handle->format);
153 return false;
154 }
155 }
156
157 if (!isBlendingSupported(layer.blending)) {
158 ALOGV("\tlayer %u: blending %d not supported", i, layer.blending);
159 mLayerInfos[i]->mCheckOverlayFlag |= eUnsupportedBlending;
160 return false;
161 }
162
163#ifdef USE_FB_PHY_LINEAR
164 if (CC_UNLIKELY(isOffscreen(layer, mXres, mYres))) {
165 ALOGW("\tlayer %u: off-screen", i);
166 return false;
167 }
168#endif
169
170 return true;
171}
172
173int ExynosOverlayDisplay::prepare(hwc_display_contents_1_t* contents)
174{
175 ATRACE_CALL();
176 ALOGV("preparing %u layers for FIMD", contents->numHwLayers);
177
178 memset(mPostData.gsc_map, 0, sizeof(mPostData.gsc_map));
179
180 mForceFb = mHwc->force_gpu;
181
182 checkTVBandwidth();
183
184 mForceFbYuvLayer = 0;
185 mConfigMode = 0;
186 mRetry = false;
187
188 ExynosDisplay::allocateLayerInfos(contents);
189 /*
190 * check whether same config or different config,
191 * should be waited until meeting the NUM_COFIG)STABLE
192 * before stablizing config, should be composed by GPU
193 * faster stablizing config, should be returned by OVERLAY
194 */
195 forceYuvLayersToFb(contents);
196
197 if (mHwc->force_gpu == true)
198 mForceFb = true;
199
200 do {
201#ifdef G2D_COMPOSITION
202 int tot_pixels = 0;
203 mG2dLayers= 0;
204 memset(&mG2d, 0, sizeof(mG2d));
205 mG2dComposition = 0;
206
207 if (contents->flags & HWC_GEOMETRY_CHANGED) {
208 mG2dBypassCount = 4;
209 goto SKIP_G2D_OVERLAY;
210 }
211
212 if (mG2dBypassCount > 0)
213 goto SKIP_G2D_OVERLAY;
214
215 for (size_t i = 0; i < contents->numHwLayers; i++) {
216 hwc_layer_1_t &layer = contents->hwLayers[i];
217
218 if ((layer.compositionType == HWC_FRAMEBUFFER_TARGET) ||
219 (layer.compositionType == HWC_BACKGROUND && !mForceFb))
220 continue;
221
222 if (is_transformed(layer) || is_scaled(layer) || (!layer.handle))
223 goto SKIP_G2D_OVERLAY;
224
225 private_handle_t *handle = private_handle_t::dynamicCast(layer.handle);
226 if (!exynos5_format_is_rgb(handle->format))
227 goto SKIP_G2D_OVERLAY;
228
229 tot_pixels += WIDTH(layer.displayFrame) * HEIGHT(layer.displayFrame);
230 }
231
232 if ((tot_pixels == mXres * mYres) &&
233 (contents->numHwLayers <= NUM_HW_WINDOWS + 1))
234 mG2dComposition = 1;
235 else
236 mG2dComposition = 0;
237
238 SKIP_G2D_OVERLAY:
239#endif
240
241 determineYuvOverlay(contents);
242 determineSupportedOverlays(contents);
243 determineBandwidthSupport(contents);
244 assignWindows(contents);
245 } while (mRetry);
246
247#ifdef G2D_COMPOSITION
248 int alloc_fail = 0;
249CHANGE_COMPOS_MODE:
250 if (mG2dComposition) {
251 if (mGscUsed || mFbNeeded || alloc_fail) {
252 //use SKIP_STATIC_LAYER_COMP
253 for (size_t i = 0; i < (size_t)mG2dLayers; i++) {
254 int lay_idx = mG2d.ovly_lay_idx[i];
255 hwc_layer_1_t &layer = contents->hwLayers[lay_idx];
256 layer.compositionType = HWC_FRAMEBUFFER;
257 mFbNeeded = true;
258 for (size_t j = 0; j < NUM_HW_WIN_FB_PHY; j++) {
259 if (mPostData.overlay_map[j] == lay_idx) {
260 mPostData.overlay_map[j] = -1;
261 break;
262 }
263 }
264 }
265 if (mFbNeeded)
266 mFirstFb = min(mFirstFb, (size_t)mG2d.ovly_lay_idx[0]);
267 mG2dLayers= 0;
268 mG2dComposition = 0;
269 }
270 }
271
272 if (mG2dComposition) {
273 alloc_fail = exynos5_g2d_buf_alloc(mHwc, contents);
274 if (alloc_fail)
275 goto CHANGE_COMPOS_MODE;
276 }
277
278 if (contents->flags & HWC_GEOMETRY_CHANGED) {
279 for (int i = 0; i < (int)NUM_HW_WIN_FB_PHY; i++)
280 mLastG2dLayerHandle[i] = 0;
281 }
282#endif
283
284 if (mPopupPlayYuvContents)
285 mVirtualOverlayFlag = 0;
286 else
287 skipStaticLayers(contents);
288 if (mVirtualOverlayFlag)
289 mFbNeeded = 0;
290
291 if (!mFbNeeded)
292 mPostData.fb_window = NO_FB_NEEDED;
293 else
294 if (mPopupPlayYuvContents)
295 mPostData.fb_window = 1;
296
297 return 0;
298}
299
300void ExynosOverlayDisplay::configureOtfWindow(hwc_rect_t &displayFrame,
301 int32_t blending, int32_t planeAlpha, int fence_fd, int format, s3c_fb_win_config &cfg)
302{
303 uint8_t bpp = formatToBpp(format);
304
305 cfg.state = cfg.S3C_FB_WIN_STATE_OTF;
306 cfg.fd = -1;
307 cfg.x = displayFrame.left;
308 cfg.y = displayFrame.top;
309 cfg.w = WIDTH(displayFrame);
310 cfg.h = HEIGHT(displayFrame);
311 cfg.format = halFormatToS3CFormat(format);
312 cfg.offset = 0;
313 cfg.stride = cfg.w * bpp / 8;
314 cfg.blending = halBlendingToS3CBlending(blending);
315 cfg.fence_fd = fence_fd;
316 cfg.plane_alpha = 255;
317 if (planeAlpha && (planeAlpha < 255)) {
318 cfg.plane_alpha = planeAlpha;
319 }
320}
321
322void ExynosOverlayDisplay::configureHandle(private_handle_t *handle,
323 hwc_frect_t &sourceCrop, hwc_rect_t &displayFrame,
324 int32_t blending, int32_t planeAlpha, int fence_fd, s3c_fb_win_config &cfg)
325{
326 uint32_t x, y;
327 uint32_t w = WIDTH(displayFrame);
328 uint32_t h = HEIGHT(displayFrame);
329 uint8_t bpp = formatToBpp(handle->format);
330 uint32_t offset = ((uint32_t)sourceCrop.top * handle->stride + (uint32_t)sourceCrop.left) * bpp / 8;
331
332 if (displayFrame.left < 0) {
333 unsigned int crop = -displayFrame.left;
334 ALOGV("layer off left side of screen; cropping %u pixels from left edge",
335 crop);
336 x = 0;
337 w -= crop;
338 offset += crop * bpp / 8;
339 } else {
340 x = displayFrame.left;
341 }
342
343 if (displayFrame.right > this->mXres) {
344 unsigned int crop = displayFrame.right - this->mXres;
345 ALOGV("layer off right side of screen; cropping %u pixels from right edge",
346 crop);
347 w -= crop;
348 }
349
350 if (displayFrame.top < 0) {
351 unsigned int crop = -displayFrame.top;
352 ALOGV("layer off top side of screen; cropping %u pixels from top edge",
353 crop);
354 y = 0;
355 h -= crop;
356 offset += handle->stride * crop * bpp / 8;
357 } else {
358 y = displayFrame.top;
359 }
360
361 if (displayFrame.bottom > this->mYres) {
362 int crop = displayFrame.bottom - this->mYres;
363 ALOGV("layer off bottom side of screen; cropping %u pixels from bottom edge",
364 crop);
365 h -= crop;
366 }
367
368 cfg.state = cfg.S3C_FB_WIN_STATE_BUFFER;
369 cfg.fd = handle->fd;
370 cfg.x = x;
371 cfg.y = y;
372 cfg.w = w;
373 cfg.h = h;
374 cfg.format = halFormatToS3CFormat(handle->format);
375 cfg.offset = offset;
376 cfg.stride = handle->stride * bpp / 8;
377 cfg.blending = halBlendingToS3CBlending(blending);
378 cfg.fence_fd = fence_fd;
379 cfg.plane_alpha = 255;
380 if (planeAlpha && (planeAlpha < 255)) {
381 cfg.plane_alpha = planeAlpha;
382 }
383#ifdef USES_DRM_SETTING_BY_DECON
384 if (getDrmMode(handle->flags) != NO_DRM)
385 cfg.protection = 1;
386 else
387 cfg.protection = 0;
388#endif
389}
390
391void ExynosOverlayDisplay::configureOverlay(hwc_layer_1_t *layer, s3c_fb_win_config &cfg)
392{
393 hwc_rect_t displayFrame;
394
395 displayFrame.left = layer->displayFrame.left;
396 displayFrame.top = layer->displayFrame.top;
397 displayFrame.right = layer->displayFrame.right;
398 displayFrame.bottom = layer->displayFrame.bottom;
399
400 if (layer->compositionType == HWC_BACKGROUND) {
401 hwc_color_t color = layer->backgroundColor;
402 cfg.state = cfg.S3C_FB_WIN_STATE_COLOR;
403 cfg.color = (color.r << 16) | (color.g << 8) | color.b;
404 cfg.x = 0;
405 cfg.y = 0;
406 cfg.w = this->mXres;
407 cfg.h = this->mYres;
408 return;
409 }
410 if ((layer->acquireFenceFd >= 0) && this->mForceFbYuvLayer) {
411 if (sync_wait(layer->acquireFenceFd, 1000) < 0)
412 ALOGE("sync_wait error");
413 close(layer->acquireFenceFd);
414 layer->acquireFenceFd = -1;
415 }
416 private_handle_t *handle = private_handle_t::dynamicCast(layer->handle);
417 hwc_frect_t originalCrop = layer->sourceCropf;
418 if (layer->compositionType == HWC_FRAMEBUFFER_TARGET) {
419 layer->sourceCropf.left = (double)mFbUpdateRegion.left;
420 layer->sourceCropf.top = (double)mFbUpdateRegion.top;
421 layer->sourceCropf.right = (double)mFbUpdateRegion.right;
422 layer->sourceCropf.bottom = (double)mFbUpdateRegion.bottom;
423 displayFrame.left = mFbUpdateRegion.left;
424 displayFrame.top = mFbUpdateRegion.top;
425 displayFrame.right = mFbUpdateRegion.right;
426 displayFrame.bottom = mFbUpdateRegion.bottom;
427 }
428 configureHandle(handle, layer->sourceCropf, displayFrame,
429 layer->blending, layer->planeAlpha, layer->acquireFenceFd, cfg);
430 layer->sourceCropf = originalCrop;
431}
432
433void ExynosOverlayDisplay::configureDummyOverlay(hwc_layer_1_t *layer, s3c_fb_win_config &cfg)
434{
435 hwc_rect_t displayFrame;
436
437 displayFrame.left = layer->displayFrame.left;
438 displayFrame.top = layer->displayFrame.top;
439 displayFrame.right = layer->displayFrame.right;
440 displayFrame.bottom = layer->displayFrame.bottom;
441
442 if (layer->acquireFenceFd >= 0) {
443 close(layer->acquireFenceFd);
444 layer->acquireFenceFd = -1;
445 }
446
447 uint32_t x, y;
448 uint32_t w = WIDTH(displayFrame);
449 uint32_t h = HEIGHT(displayFrame);
450
451 if (displayFrame.left < 0) {
452 unsigned int crop = -displayFrame.left;
453 x = 0;
454 w -= crop;
455 } else {
456 x = displayFrame.left;
457 }
458
459 if (displayFrame.right > this->mXres) {
460 unsigned int crop = displayFrame.right - this->mXres;
461 w -= crop;
462 }
463
464 if (displayFrame.top < 0) {
465 unsigned int crop = -displayFrame.top;
466 y = 0;
467 h -= crop;
468 } else {
469 y = displayFrame.top;
470 }
471
472 if (displayFrame.bottom > this->mYres) {
473 int crop = displayFrame.bottom - this->mYres;
474 h -= crop;
475 }
476
477 cfg.state = cfg.S3C_FB_WIN_STATE_COLOR;
478 cfg.color = 0;
479
480 cfg.x = x;
481 cfg.y = y;
482 cfg.w = w;
483 cfg.h = h;
484 cfg.fence_fd = -1;
485
486 return;
487}
488
489int ExynosOverlayDisplay::handleWindowUpdate(hwc_display_contents_1_t* contents,
490 struct s3c_fb_win_config *config)
491{
492 exynos5_hwc_post_data_t *pdata = &mPostData;
493 int layerIdx = -1;
494 int updatedWinCnt = 0;
495 int totalWinCnt = 0;
496 int bytePerPixel = 0;
497 size_t winUpdateInfoIdx;
498 hwc_rect updateRect = {this->mXres, this->mYres, 0, 0};
499 hwc_rect currentRect = {0, 0, 0, 0};
500 bool burstLengthCheckDone = false;
501 int alignAdjustment = 0;
502 int intersectionWidth = 0;
503
504 char value[PROPERTY_VALUE_MAX];
2bd61160 505 property_get("debug.hwc.winupdate", value, "1");
5763fb39
T
506
507 if (!(!strcmp(value, "1") || !strcmp(value, "true")))
508 return 0;
509
510 if (S3C_WIN_UPDATE_IDX < 0)
511 return 0;
512 winUpdateInfoIdx = S3C_WIN_UPDATE_IDX;
513
514 if (contents->flags & HWC_GEOMETRY_CHANGED)
515 return 0;
516
517 for (size_t i = 0; i < NUM_HW_WINDOWS; i++) {
518 if (config[i].state != config[i].S3C_FB_WIN_STATE_DISABLED) {
519 if (mLastGscMap[i].mode == exynos5_gsc_map_t::GSC_LOCAL) {
520 HLOGV("[WIN_UPDATE] disabled by GSC-OTF in window(%d)", i);
521 return 0;
522 }
523 totalWinCnt++;
524 layerIdx = pdata->overlay_map[totalWinCnt - 1];
525
526 if (winConfigChanged(&config[i], &this->mLastConfigData.config[i])) {
527 updatedWinCnt++;
528
529 currentRect.left = config[i].x;
530 currentRect.right = config[i].x + config[i].w;
531 currentRect.top = config[i].y;
532 currentRect.bottom = config[i].y + config[i].h;
533
534 if (hwcHasApiVersion((hwc_composer_device_1_t*)mHwc, HWC_DEVICE_API_VERSION_1_5))
535 {
536 private_handle_t *handle = NULL;
537 hwc_rect damageRect = {0, 0, 0, 0};
538 hwc_layer_1_t &layer = contents->hwLayers[i];
539 if (layer.handle)
540 handle = private_handle_t::dynamicCast(layer.handle);
541 unsigned int damageRegionMod = getLayerRegion(layer, damageRect, eDamageRegion);
542
543 if (damageRegionMod == eDamageRegionSkip)
544 continue;
545
546 if (handle && !isScaled(layer) && !isRotated(layer)
547 && (damageRegionMod == eDamageRegionPartial)) {
548 HLOGD("[WIN_UPDATE][surfaceDamage] layer w(%4d) h(%4d), dirty (%4d, %4d) - (%4d, %4d)",
549 handle->width, handle->height, damageRect.left, damageRect.top, damageRect.right, damageRect.bottom);
550
551 currentRect.left = config[i].x - (int32_t)layer.sourceCropf.left + damageRect.left;
552 currentRect.right = config[i].x - (int32_t)layer.sourceCropf.left + damageRect.right;
553 currentRect.top = config[i].y - (int32_t)layer.sourceCropf.top + damageRect.top;
554 currentRect.bottom = config[i].y - (int32_t)layer.sourceCropf.top + damageRect.bottom;
555 adjustRect(currentRect, mXres, mYres);
556
557 }
558 }
559 if ((currentRect.left > currentRect.right) || (currentRect.top > currentRect.bottom)) {
560 HLOGD("[WIN_UPDATE] window(%d) layer(%d) invalid region (%4d, %4d) - (%4d, %4d)",
561 i, layerIdx, currentRect.left, currentRect.top, currentRect.right, currentRect.bottom);
562 return 0;
563 }
564 HLOGD("[WIN_UPDATE] Updated Window(%d) Layer(%d) (%4d, %4d) - (%4d, %4d)",
565 i, layerIdx, currentRect.left, currentRect.top, currentRect.right, currentRect.bottom);
566 updateRect = expand(updateRect, currentRect);
567 }
568 }
569 }
570 if (updatedWinCnt == 0)
571 return 0;
572
573 updateRect.left = ALIGN_DOWN(updateRect.left, WINUPDATE_X_ALIGNMENT);
574 updateRect.right = updateRect.left + ALIGN_UP(WIDTH(updateRect), WINUPDATE_W_ALIGNMENT);
575
576 if ((100 * (WIDTH(updateRect) * HEIGHT(updateRect)) / (this->mXres * this->mYres)) > WINUPDATE_THRESHOLD)
577 return 0;
578
579 alignAdjustment = max(WINUPDATE_X_ALIGNMENT, WINUPDATE_W_ALIGNMENT);
580
581 while (1) {
582 burstLengthCheckDone = true;
583
584 for (int i = 0; i < NUM_HW_WINDOWS; i++) {
585 if (config[i].state != config[i].S3C_FB_WIN_STATE_DISABLED) {
586 if (config[i].format == S3C_FB_PIXEL_FORMAT_RGB_565)
587 bytePerPixel = 2;
588 else
589 bytePerPixel = 4;
590
591 currentRect.left = config[i].x;
592 currentRect.right = config[i].x + config[i].w;
593 currentRect.top = config[i].y;
594 currentRect.bottom = config[i].y + config[i].h;
595
596 intersectionWidth = WIDTH(intersection(currentRect, updateRect));
597
598 HLOGV("[WIN_UPDATE] win[%d] left(%d) right(%d) intersection(%d)", i, currentRect.left, currentRect.right, intersectionWidth);
599
600 if (intersectionWidth != 0 && intersectionWidth * bytePerPixel < BURSTLEN_BYTES) {
601 HLOGV("[WIN_UPDATE] win[%d] insufficient burst length (%d)*(%d) < %d", i, intersectionWidth, bytePerPixel, BURSTLEN_BYTES);
602 burstLengthCheckDone = false;
603 break;
604 }
605 }
606 }
607 if (burstLengthCheckDone)
608 break;
609 HLOGD("[WIN_UPDATE] Adjusting update width. current left(%d) right(%d)", updateRect.left, updateRect.right);
610 if (updateRect.left >= alignAdjustment) {
611 updateRect.left -= alignAdjustment;
612 } else if (updateRect.right + alignAdjustment <= this->mXres) {
613 updateRect.right += alignAdjustment;
614 } else {
615 ALOGD("[WIN_UPDATE] Error during update width adjustment");
616 return 0;
617 }
618 }
619
620 config[winUpdateInfoIdx].state = config[winUpdateInfoIdx].S3C_FB_WIN_STATE_UPDATE;
621 config[winUpdateInfoIdx].x = updateRect.left;
622 config[winUpdateInfoIdx].y = updateRect.top;
623 config[winUpdateInfoIdx].w = ALIGN_UP(WIDTH(updateRect), WINUPDATE_W_ALIGNMENT);
624 config[winUpdateInfoIdx].h = HEIGHT(updateRect);
625
626 HLOGD("[WIN_UPDATE] UpdateRegion cfg (%4d, %4d) w(%4d) h(%4d) updatedWindowCnt(%d)",
627 config[winUpdateInfoIdx].x, config[winUpdateInfoIdx].y, config[winUpdateInfoIdx].w, config[winUpdateInfoIdx].h, updatedWinCnt);
628
629 return 1;
630}
631
632int ExynosOverlayDisplay::winconfigIoctl(s3c_fb_win_config_data *win_data)
633{
634 ATRACE_CALL();
635 return ioctl(this->mDisplayFd, S3CFB_WIN_CONFIG, win_data);
636}
637
638int ExynosOverlayDisplay::postFrame(hwc_display_contents_1_t* contents)
639{
640 ATRACE_CALL();
641 exynos5_hwc_post_data_t *pdata = &mPostData;
642 struct s3c_fb_win_config_data win_data;
643 struct s3c_fb_win_config *config = win_data.config;
644 int win_map = 0;
645 int tot_ovly_wins = 0;
646
647#ifdef G2D_COMPOSITION
648 int num_g2d_overlayed = 0;
649#endif
650
651 memset(config, 0, sizeof(win_data.config));
652 for (size_t i = 0; i < NUM_HW_WINDOWS; i++)
653 config[i].fence_fd = -1;
654
655 for (size_t i = 0; i < NUM_HW_WINDOWS; i++) {
656 if ( pdata->overlay_map[i] != -1)
657 tot_ovly_wins++;
658 }
659 if (mVirtualOverlayFlag)
660 tot_ovly_wins++;
661
662 for (size_t i = 0; i < NUM_HW_WINDOWS; i++) {
663 int layer_idx = pdata->overlay_map[i];
664 if (layer_idx != -1) {
665 hwc_layer_1_t &layer = contents->hwLayers[layer_idx];
666 win_map = getDeconWinMap(i, tot_ovly_wins);
667 if (pdata->gsc_map[i].mode == exynos5_gsc_map_t::GSC_M2M) {
668 if (contents->flags & HWC_GEOMETRY_CHANGED)
669 mMPPs[pdata->gsc_map[i].idx]->mLastGSCLayerHandle = -1;
670 if (postGscM2M(layer, config, win_map, i, !!(i == 0)) < 0)
671 continue;
672 } else if (pdata->gsc_map[i].idx == FIMD_GSC_IDX && this->mOtfMode == OTF_RUNNING &&
673 pdata->gsc_map[i].mode == exynos5_gsc_map_t::GSC_LOCAL) {
674 postGscOtf(layer, config, win_map, i);
675#ifdef G2D_COMPOSITION
676 } else if (this->mG2dComposition && (num_g2d_overlayed < this->mG2dLayers)){
677 waitForRenderFinish(&layer.handle, 1);
678 private_handle_t dstHandle(*(private_handle_t::dynamicCast(layer.handle)));
679 hwc_frect_t sourceCrop = {0, 0, WIDTH(layer.displayFrame), HEIGHT(layer.displayFrame)};
680 int fence = exynos5_config_g2d(mHwc, layer, &dstHandle, config[win_map], num_g2d_overlayed, i);
681 if (fence < 0) {
682 ALOGE("config_g2d failed for layer %u", i);
683 continue;
684 }
685 configureHandle(&dstHandle, sourceCrop, layer.displayFrame,
686 layer.blending, layer.planeAlpha, fence, *config);
687 num_g2d_overlayed++;
688 this->mG2d.win_used[i] = num_g2d_overlayed;
689#endif
690 } else {
691 waitForRenderFinish(&layer.handle, 1);
692 configureOverlay(&layer, config[win_map]);
693 }
694 }
695 if (i == 0 && config[i].blending != S3C_FB_BLENDING_NONE) {
696 ALOGV("blending not supported on window 0; forcing BLENDING_NONE");
697 config[i].blending = S3C_FB_BLENDING_NONE;
698 }
699 if ((i < S3C_WIN_UPDATE_IDX) &&
700 (config[i].state != config[i].S3C_FB_WIN_STATE_DISABLED) &&
701 (config[i].w == 0 || config[i].h == 0)) {
702 config[i].state = config[i].S3C_FB_WIN_STATE_DISABLED;
703 }
704
705 ALOGV("window %u configuration:", i);
706 dumpConfig(config[win_map]);
707 }
708
709 if (this->mVirtualOverlayFlag) {
710 handleStaticLayers(contents, win_data, tot_ovly_wins);
711 }
712
713 if (!handleWindowUpdate(contents, config))
714 HLOGD("[WIN_UPDATE] Not Triggered");
715
716 int ret = winconfigIoctl(&win_data);
717 for (size_t i = 0; i < NUM_HW_WINDOWS; i++)
718 if (config[i].fence_fd != -1)
719 close(config[i].fence_fd);
720 if (ret < 0) {
721 ALOGE("ioctl S3CFB_WIN_CONFIG failed: %s", strerror(errno));
722 return ret;
723 }
724 if (contents->numHwLayers == 1) {
725 hwc_layer_1_t &layer = contents->hwLayers[0];
726 if (layer.acquireFenceFd >= 0)
727 close(layer.acquireFenceFd);
728 }
729
730 if (!mGscLayers || this->mOtfMode == OTF_TO_M2M) {
731 cleanupGscs();
732 }
733
734#ifdef G2D_COMPOSITION
735 if (!this->mG2dComposition)
736 exynos5_cleanup_g2d(mHwc, 0);
737
738 this->mG2dBypassCount = max( this->mG2dBypassCount-1, 0);
739#endif
740
741 memcpy(&(this->mLastConfigData), &win_data, sizeof(win_data));
742 memcpy(this->mLastGscMap, pdata->gsc_map, sizeof(pdata->gsc_map));
743 if (!this->mVirtualOverlayFlag)
744 this->mLastFbWindow = pdata->fb_window;
745 for (size_t i = 0; i < NUM_HW_WINDOWS; i++) {
746 int layer_idx = pdata->overlay_map[i];
747 if (layer_idx != -1) {
748 hwc_layer_1_t &layer = contents->hwLayers[layer_idx];
749 win_map = getDeconWinMap(i, tot_ovly_wins);
750 this->mLastHandles[win_map] = layer.handle;
751 }
752 }
753
754 return win_data.fence;
755}
756
757int ExynosOverlayDisplay::clearDisplay()
758{
759 struct s3c_fb_win_config_data win_data;
760 memset(&win_data, 0, sizeof(win_data));
761
762 int ret = ioctl(this->mDisplayFd, S3CFB_WIN_CONFIG, &win_data);
763 LOG_ALWAYS_FATAL_IF(ret < 0,
764 "ioctl S3CFB_WIN_CONFIG failed to clear screen: %s",
765 strerror(errno));
766 // the causes of an empty config failing are all unrecoverable
767
768 return win_data.fence;
769}
770
771int ExynosOverlayDisplay::set(hwc_display_contents_1_t* contents)
772{
773 hwc_layer_1_t *fb_layer = NULL;
774 int err = 0;
775
776 if (this->mPostData.fb_window != NO_FB_NEEDED) {
777 for (size_t i = 0; i < contents->numHwLayers; i++) {
778 if (contents->hwLayers[i].compositionType ==
779 HWC_FRAMEBUFFER_TARGET) {
780 this->mPostData.overlay_map[this->mPostData.fb_window] = i;
781 fb_layer = &contents->hwLayers[i];
782 break;
783 }
784 }
785
786 if (CC_UNLIKELY(!fb_layer)) {
787 ALOGE("framebuffer target expected, but not provided");
788 err = -EINVAL;
789 } else {
790 ALOGV("framebuffer target buffer:");
791 dumpLayer(fb_layer);
792 }
793 }
794
795 for (size_t i = 0; i < contents->numHwLayers; i++) {
796 if (contents->hwLayers[i].compositionType == HWC_OVERLAY &&
797 contents->hwLayers[i].planeAlpha == 0) {
798 close(contents->hwLayers[i].acquireFenceFd);
799 contents->hwLayers[i].acquireFenceFd = -1;
800 contents->hwLayers[i].releaseFenceFd = -1;
801 }
802 }
803
804 int fence;
805 if (!err) {
806 fence = postFrame(contents);
807 if (fence < 0)
808 err = fence;
809 }
810
811 if (err)
812 fence = clearDisplay();
813
814 for (size_t i = 0; i < NUM_HW_WINDOWS; i++) {
815 if (this->mPostData.overlay_map[i] != -1) {
816 hwc_layer_1_t &layer =
817 contents->hwLayers[this->mPostData.overlay_map[i]];
818 int dup_fd = dup(fence);
819 if (dup_fd < 0)
820 ALOGW("release fence(%d) dup failed : %s", fence, strerror(errno));
821 if (this->mPostData.gsc_map[i].mode == exynos5_gsc_map_t::GSC_M2M) {
822 int gsc_idx = this->mPostData.gsc_map[i].idx;
823 ExynosMPP &gsc = *mMPPs[gsc_idx];
824 if (gsc.mDstBufFence[gsc.mCurrentBuf] >= 0) {
825 close (gsc.mDstBufFence[gsc.mCurrentBuf]);
826 gsc.mDstBufFence[gsc.mCurrentBuf] = -1;
827 }
828 gsc.mDstBufFence[gsc.mCurrentBuf] = dup_fd;
829 gsc.mCurrentBuf = (gsc.mCurrentBuf + 1) % gsc.mNumAvailableDstBuffers;
830 } else if (this->mPostData.gsc_map[i].mode == exynos5_gsc_map_t::GSC_LOCAL) {
831 layer.releaseFenceFd = dup_fd;
832#ifdef G2D_COMPOSITION
833 } else if (this->mG2dComposition && this->mG2d.win_used[i]) {
834 int idx = this->mG2d.win_used[i] - 1;
835 this->mWinBufFence[idx][this->mG2dCurrentBuffer[idx]] = dup_fd;
836 this->mG2dCurrentBuffer[idx] = (this->mG2dCurrentBuffer[idx] + 1) % NUM_GSC_DST_BUFS;
837#endif
838 } else {
839 layer.releaseFenceFd = dup_fd;
840 }
841 }
842 }
843
844 if (contents->numHwLayers >= 1) {
845 hwc_layer_1_t &layer = contents->hwLayers[contents->numHwLayers-1];
846
847 if (mVirtualOverlayFlag && layer.compositionType == HWC_FRAMEBUFFER_TARGET) {
848 int dup_fd = dup(fence);
849 if (dup_fd < 0) {
850 ALOGW("release fence(%d) dup failed in FB_TARGET: %s", fence, strerror(errno));
851 } else {
852 layer.releaseFenceFd = dup_fd;
853 }
854 }
855 }
856
857 contents->retireFenceFd = fence;
858
859 mHwc->hwc_ctrl.max_num_ovly = mAllowedOverlays;
860
861 return err;
862}
863
864int ExynosOverlayDisplay::getCompModeSwitch()
865{
866 unsigned int tot_win_size = 0, updateFps = 0;
867 unsigned int lcd_size = this->mXres * this->mYres;
868 uint64_t TimeStampDiff;
869 float Temp;
870
871 if (!mHwc->hwc_ctrl.dynamic_recomp_mode) {
872 mHwc->LastModeSwitchTimeStamp = 0;
873 mHwc->CompModeSwitch = NO_MODE_SWITCH;
874 return 0;
875 }
876
877 /* initialize the Timestamps */
878 if (!mHwc->LastModeSwitchTimeStamp) {
879 mHwc->LastModeSwitchTimeStamp = mHwc->LastUpdateTimeStamp;
880 mHwc->CompModeSwitch = NO_MODE_SWITCH;
881 return 0;
882 }
883
884 /* If video layer is there, skip the mode switch */
885 if (mYuvLayers || mGscLayers >= 2 ) {
886 if (mHwc->CompModeSwitch != HWC_2_GLES) {
887 return 0;
888 } else {
889 mHwc->CompModeSwitch = GLES_2_HWC;
890 mHwc->updateCallCnt = 0;
891 mHwc->LastModeSwitchTimeStamp = mHwc->LastUpdateTimeStamp;
892 ALOGI("[DYNAMIC_RECOMP] GLES_2_HWC by video layer");
893 return GLES_2_HWC;
894 }
895 }
896
897 /* Mode Switch is not required if total pixels are not more than the threshold */
898 if ((uint32_t)mHwc->incomingPixels <= lcd_size * HWC_FIMD_BW_TH) {
899 if (mHwc->CompModeSwitch != HWC_2_GLES) {
900 return 0;
901 } else {
902 mHwc->CompModeSwitch = GLES_2_HWC;
903 mHwc->updateCallCnt = 0;
904 mHwc->LastModeSwitchTimeStamp = mHwc->LastUpdateTimeStamp;
905 ALOGI("[DYNAMIC_RECOMP] GLES_2_HWC by BW check");
906 return GLES_2_HWC;
907 }
908 }
909
910 /*
911 * There will be at least one composition call per one minute (because of time update)
912 * To minimize the analysis overhead, just analyze it once in a second
913 */
914 TimeStampDiff = systemTime(SYSTEM_TIME_MONOTONIC) - mHwc->LastModeSwitchTimeStamp;
915
916 /* check fps every 250ms from LastModeSwitchTimeStamp*/
917 if (TimeStampDiff < (VSYNC_INTERVAL * 15)) {
918 return 0;
919 }
920 mHwc->LastModeSwitchTimeStamp = mHwc->LastUpdateTimeStamp;
921 Temp = (VSYNC_INTERVAL * 60) / TimeStampDiff;
922 updateFps = (int)(mHwc->updateCallCnt * Temp + 0.5);
923 mHwc->updateCallCnt = 0;
924 /*
925 * FPS estimation.
926 * If FPS is lower than HWC_FPS_TH, try to switch the mode to GLES
927 */
928 if (updateFps < HWC_FPS_TH) {
929 if (mHwc->CompModeSwitch != HWC_2_GLES) {
930 mHwc->CompModeSwitch = HWC_2_GLES;
931 ALOGI("[DYNAMIC_RECOMP] HWC_2_GLES by low FPS(%d)", updateFps);
932 return HWC_2_GLES;
933 } else {
934 return 0;
935 }
936 } else {
937 if (mHwc->CompModeSwitch == HWC_2_GLES) {
938 mHwc->CompModeSwitch = GLES_2_HWC;
939 ALOGI("[DYNAMIC_RECOMP] GLES_2_HWC by high FPS(%d)", updateFps);
940 return GLES_2_HWC;
941 } else {
942 return 0;
943 }
944 }
945
946 return 0;
947}
948
949int32_t ExynosOverlayDisplay::getDisplayAttributes(const uint32_t attribute)
950{
951 switch(attribute) {
952 case HWC_DISPLAY_VSYNC_PERIOD:
953 return this->mVsyncPeriod;
954
955 case HWC_DISPLAY_WIDTH:
956 return this->mXres;
957
958 case HWC_DISPLAY_HEIGHT:
959 return this->mYres;
960
961 case HWC_DISPLAY_DPI_X:
962 return this->mXdpi;
963
964 case HWC_DISPLAY_DPI_Y:
965 return this->mYdpi;
966
967 default:
968 ALOGE("unknown display attribute %u", attribute);
969 return -EINVAL;
970 }
971}
972
973void ExynosOverlayDisplay::skipStaticLayers(hwc_display_contents_1_t* contents)
974{
975 static int init_flag = 0;
976 int last_ovly_lay_idx = -1;
977
978 mVirtualOverlayFlag = 0;
979 mLastOverlayWindowIndex = -1;
980
981 if (!mHwc->hwc_ctrl.skip_static_layer_mode)
982 return;
983
984 if (mBypassSkipStaticLayer)
985 return;
986
987 if (contents->flags & HWC_GEOMETRY_CHANGED) {
988 init_flag = 0;
989 return;
990 }
991
992 for (size_t i = 0; i < NUM_HW_WINDOWS; i++) {
993 if (mPostData.overlay_map[i] != -1) {
994 last_ovly_lay_idx = mPostData.overlay_map[i];
995 mLastOverlayWindowIndex = i;
996 }
997 }
998
999 if ((last_ovly_lay_idx == -1) || !mFbNeeded ||
1000 ((mLastFb - mFirstFb + 1) > NUM_VIRT_OVER)) {
1001 init_flag = 0;
1002 return;
1003 }
1004 mLastOverlayLayerIndex = last_ovly_lay_idx;
1005
1006 if (init_flag == 1) {
1007 for (size_t i = mFirstFb; i <= mLastFb; i++) {
1008 hwc_layer_1_t &layer = contents->hwLayers[i];
1009 if (!layer.handle || (layer.flags & HWC_SKIP_LAYER) || (mLastLayerHandles[i - mFirstFb] != layer.handle)) {
1010 init_flag = 0;
1011 return;
1012 }
1013 }
1014
1015 mVirtualOverlayFlag = 1;
1016 for (size_t i = 0; i < contents->numHwLayers-1; i++) {
1017 hwc_layer_1_t &layer = contents->hwLayers[i];
1018 if (layer.compositionType == HWC_FRAMEBUFFER) {
1019 layer.compositionType = HWC_OVERLAY;
1020 mLayerInfos[i]->compositionType = layer.compositionType;
1021 mLayerInfos[i]->mCheckOverlayFlag |= eSkipStaticLayer;
1022 }
1023 }
1024 mLastFbWindow = mPostData.fb_window;
1025 return;
1026 }
1027
1028 init_flag = 1;
1029 for (size_t i = 0; i < NUM_VIRT_OVER; i++)
1030 mLastLayerHandles[i] = 0;
1031
1032 for (size_t i = mFirstFb; i <= mLastFb; i++) {
1033 hwc_layer_1_t &layer = contents->hwLayers[i];
1034 mLastLayerHandles[i - mFirstFb] = layer.handle;
1035 }
1036
1037 return;
1038}
1039
1040void ExynosOverlayDisplay::forceYuvLayersToFb(hwc_display_contents_1_t *contents)
1041{
1042}
1043
1044void ExynosOverlayDisplay::handleOffscreenRendering(hwc_layer_1_t &layer, hwc_display_contents_1_t *contents, int index)
1045{
1046}
1047
1048void ExynosOverlayDisplay::determineYuvOverlay(hwc_display_contents_1_t *contents)
1049{
1050 mPopupPlayYuvContents = false;
1051 mForceOverlayLayerIndex = -1;
1052 mHasDrmSurface = false;
1053 mYuvLayers = 0;
1054 mHasCropSurface = false;
1055 for (size_t i = 0; i < contents->numHwLayers; i++) {
1056 hwc_layer_1_t &layer = contents->hwLayers[i];
1057 if (layer.handle) {
1058 private_handle_t *handle = private_handle_t::dynamicCast(layer.handle);
1059 if (getDrmMode(handle->flags) != NO_DRM) {
1060 this->mHasDrmSurface = true;
1061 mForceOverlayLayerIndex = i;
1062 }
1063
1064 /* check yuv surface */
1065 if (mMPPs[0]->formatRequiresGsc(handle->format)) {
1066 layer.sourceCropf.top = (int)layer.sourceCropf.top;
1067 layer.sourceCropf.left = (int)layer.sourceCropf.left;
1068 layer.sourceCropf.bottom = (int)(layer.sourceCropf.bottom + 0.9);
1069 layer.sourceCropf.right = (int)(layer.sourceCropf.right + 0.9);
1070 if (isOverlaySupported(contents->hwLayers[i], i)) {
1071 this->mYuvLayers++;
1072 if (this->mHasDrmSurface == false)
1073 mForceOverlayLayerIndex = i;
1074 } else if (i > 0 && layer.planeAlpha > 0) {
1075 mForceFb = true;
1076 }
1077 }
1078
1079 if (handle->flags & GRALLOC_USAGE_HW_CAMERA_MASK) {
1080 mAllowedOverlays = mHwc->hwc_ctrl.max_num_ovly;
1081 mHwc->hwc_ctrl.max_num_ovly = 3;
1082 }
1083
1084 handleOffscreenRendering(layer, contents, i);
1085 }
1086
1087#if defined(USE_GRALLOC_FLAG_FOR_HDMI) || defined(USES_VIRTUAL_DISPLAY)
1088 /* during rotation, it use gpu comosition */
1089 if (layer.flags & HWC_SCREENSHOT_ANIMATOR_LAYER)
1090 mForceFb = true;
1091#endif
1092 }
1093 mPopupPlayYuvContents = !!(((mYuvLayers == 1) || (this->mHasDrmSurface)) && (mForceOverlayLayerIndex > 0));
1094 if (mYuvLayers > 1) {
1095 mHwc->allowOTF = false;
1096 if (mMPPs[0]->isOTF())
1097 mForceFb = true;
1098 } else {
1099 mHwc->allowOTF = true;
1100 }
1101
1102#ifdef USE_FB_PHY_LINEAR
1103 if ((!mHasDrmSurface) &&
1104#ifdef G2D_COMPOSITION
1105 (mG2dBypassCount > 0) &&
1106#endif
1107 (contents->flags & HWC_GEOMETRY_CHANGED))
1108 mForceFb = true;
1109#endif
1110}
1111
1112void ExynosOverlayDisplay::determineSupportedOverlays(hwc_display_contents_1_t *contents)
1113{
1114 bool videoLayer = false;
1115
1116 mFbNeeded = false;
1117 mFirstFb = ~0;
1118 mLastFb = 0;
1119
1120 for (size_t i = 0; i < NUM_HW_WINDOWS; i++)
1121 mPostData.overlay_map[i] = -1;
1122
1123 // find unsupported overlays
1124 for (size_t i = 0; i < contents->numHwLayers; i++) {
1125 hwc_layer_1_t &layer = contents->hwLayers[i];
1126
1127 if (layer.compositionType == HWC_FRAMEBUFFER_TARGET) {
1128 ALOGV("\tlayer %u: framebuffer target", i);
1129 mLayerInfos[i]->compositionType = layer.compositionType;
1130 continue;
1131 }
1132
1133 if (layer.compositionType == HWC_BACKGROUND && !mForceFb) {
1134 ALOGV("\tlayer %u: background supported", i);
1135 dumpLayer(&contents->hwLayers[i]);
1136 mLayerInfos[i]->compositionType = layer.compositionType;
1137 continue;
1138 }
1139
1140 if (layer.handle) {
1141 private_handle_t *handle = private_handle_t::dynamicCast(layer.handle);
1142 if ((int)get_yuv_planes(halFormatToV4L2Format(handle->format)) > 0) {
1143 videoLayer = true;
1144 if (!mHwc->hdmi_hpd && mHwc->mS3DMode == S3D_MODE_READY)
1145 mHwc->mS3DMode = S3D_MODE_RUNNING;
1146 }
1147 if ((!mPopupPlayYuvContents)
1148 || ((uint32_t)mForceOverlayLayerIndex == i)) {
1149 mHwc->incomingPixels += WIDTH(layer.displayFrame) * HEIGHT(layer.displayFrame);
1150 if ((!mHasCropSurface || mPopupPlayYuvContents) ||
1151 ((mHasDrmSurface) && ((uint32_t)mForceOverlayLayerIndex == i))) {
1152 if (isOverlaySupported(contents->hwLayers[i], i) &&
1153 !(mForceFb && (getDrmMode(handle->flags) == NO_DRM)) && (!mHwc->hwc_ctrl.dynamic_recomp_mode ||
1154 ((mHwc->CompModeSwitch != HWC_2_GLES) ||
1155 (getDrmMode(handle->flags) != NO_DRM)))) {
1156 mHwc->totPixels += WIDTH(layer.displayFrame) * HEIGHT(layer.displayFrame);
1157 ALOGV("\tlayer %u: overlay supported", i);
1158 layer.compositionType = HWC_OVERLAY;
1159 mLayerInfos[i]->compositionType = layer.compositionType;
1160 if (mPopupPlayYuvContents)
1161 layer.hints = HWC_HINT_CLEAR_FB;
1162 dumpLayer(&contents->hwLayers[i]);
1163 continue;
1164 } else {
1165 if (mForceFb)
1166 mLayerInfos[i]->mCheckOverlayFlag |= eForceFbEnabled;
1167 else if (mHwc->hwc_ctrl.dynamic_recomp_mode && mHwc->CompModeSwitch == HWC_2_GLES)
1168 mLayerInfos[i]->mCheckOverlayFlag |= eDynamicRecomposition;
1169 else if (isOverlaySupported(contents->hwLayers[i], i))
1170 mLayerInfos[i]->mCheckOverlayFlag |= eUnknown;
1171 }
1172 } else {
1173 if (mHasCropSurface == true)
1174 mLayerInfos[i]->mCheckOverlayFlag |= eUnsupportedCoordinate;
1175 else
1176 mLayerInfos[i]->mCheckOverlayFlag |= eUnknown;
1177 }
1178 } else {
1179 /* There is popup video but this layer is not popup video layer */
1180 mLayerInfos[i]->mCheckOverlayFlag |= eHasPopupVideo;
1181 }
1182 } else {
1183 mLayerInfos[i]->mCheckOverlayFlag |= eInvalidHandle;
1184 }
1185
1186 if (!mFbNeeded) {
1187 mFirstFb = i;
1188 mFbNeeded = true;
1189 }
1190 mLastFb = i;
1191 layer.compositionType = HWC_FRAMEBUFFER;
1192 mLayerInfos[i]->compositionType = layer.compositionType;
1193
1194 dumpLayer(&contents->hwLayers[i]);
1195 }
1196
1197 if (!mHwc->hdmi_hpd && mHwc->mS3DMode == S3D_MODE_RUNNING && !videoLayer && !mForceFb)
1198 mHwc->mS3DMode = S3D_MODE_DISABLED;
1199 hwc_rect_t base_rect;
1200 hwc_rect_t intersect_rect;
1201 private_handle_t *handle = NULL;
1202 for (size_t i = 0; i < contents->numHwLayers; i++) {
1203 hwc_layer_1_t &layer = contents->hwLayers[i];
1204 if (layer.handle)
1205 handle = private_handle_t::dynamicCast(layer.handle);
1206 if (layer.compositionType == HWC_OVERLAY) {
1207 if (i == 0) {
1208 base_rect = layer.displayFrame;
1209 } else if (hasPlaneAlpha(layer) || (handle && hasAlpha(handle->format) && mMPPs[0]->isProcessingRequired(layer, handle->format))) {
1210 //if alpha layer is not completely overlapped with base layer, bypass the alpha layer to GLES.
1211 intersect_rect = intersection(base_rect, layer.displayFrame);
1212 if (!rectEqual(intersect_rect, layer.displayFrame)) {
1213 layer.compositionType = HWC_FRAMEBUFFER;
1214 mLayerInfos[i]->mCheckOverlayFlag |= eUnsupportedBlending;
1215 mFirstFb = min(mFirstFb, i);
1216 mLastFb = max(mLastFb, i);
1217 mFbNeeded = true;
1218 break;
1219 }
1220 }
1221 } else {
1222 // if one of the bottom layer is HWC_FRAMEBUFFER type, no need to force the alpha layer to FRAMEBUFFER type.
1223 break;
1224 }
1225 }
1226 mFirstFb = min(mFirstFb, (size_t)NUM_HW_WINDOWS-1);
1227 // can't composite overlays sandwiched between framebuffers
1228 if (mFbNeeded) {
1229 for (size_t i = mFirstFb; i < mLastFb; i++) {
1230 if (mPopupPlayYuvContents && ((uint32_t)mForceOverlayLayerIndex == i)) {
1231 mFirstFb = 1;
1232 break;
1233 }
1234 hwc_layer_1_t &layer = contents->hwLayers[i];
1235 if (layer.handle) {
1236 private_handle_t *handle = private_handle_t::dynamicCast(layer.handle);
1237 if (getDrmMode(handle->flags) == NO_DRM) {
1238 contents->hwLayers[i].compositionType = HWC_FRAMEBUFFER;
1239 mLayerInfos[i]->compositionType = contents->hwLayers[i].compositionType;
1240 mLayerInfos[i]->mCheckOverlayFlag |= eSandwitchedBetweenGLES;
1241 }
1242 }
1243 }
1244 }
1245}
1246
1247void ExynosOverlayDisplay::determineBandwidthSupport(hwc_display_contents_1_t *contents)
1248{
1249 // Incrementally try to add our supported layers to hardware windows.
1250 // If adding a layer would violate a hardware constraint, force it
1251 // into the framebuffer and try again. (Revisiting the entire list is
1252 // necessary because adding a layer to the framebuffer can cause other
1253 // windows to retroactively violate constraints.)
1254 bool changed;
1255 this->mBypassSkipStaticLayer = false;
1256 unsigned int cannotComposeFlag = 0;
1257 bool addFB = true;
1258 hwc_rect windowIntersection;
1259 windowIntersection.left = 0;
1260 windowIntersection.top = 0;
1261 windowIntersection.right = mXres;
1262 windowIntersection.bottom = mYres;
1263 int intersectionCnt = 0;
1264 bool reduceAvailableWindowCnt = false;
1265 // Initialize to inverse values so that
1266 // min(left, l) = l, min(top, t) = t
1267 // max(right, r) = r, max(bottom, b) = b
1268 // for all l, t, r, b
1269 mFbUpdateRegion.left = mXres;
1270 mFbUpdateRegion.top = mYres;
1271 mFbUpdateRegion.right = 0;
1272 mFbUpdateRegion.bottom = 0;
1273
1274 uint32_t pixel_used[MAX_NUM_FIMD_DMA_CH];
1275 do {
1276 android::Vector<hwc_rect> rects[MAX_NUM_FIMD_DMA_CH];
1277 android::Vector<hwc_rect> overlaps[MAX_NUM_FIMD_DMA_CH];
1278 int dma_ch_idx;
1279 size_t win_idx = 0;
1280 size_t windows_left;
1281 memset(&pixel_used[0], 0, sizeof(pixel_used));
1282 mGscUsed = false;
1283 windowIntersection.left = 0;
1284 windowIntersection.top = 0;
1285 windowIntersection.right = mXres;
1286 windowIntersection.bottom = mYres;
1287 intersectionCnt = 0;
1288
1289 if (mFbNeeded) {
1290 hwc_rect_t fb_rect;
1291 fb_rect.top = fb_rect.left = 0;
1292 fb_rect.right = this->mXres - 1;
1293 fb_rect.bottom = this->mYres - 1;
1294 dma_ch_idx = FIMD_DMA_CH_IDX[mFirstFb];
1295 pixel_used[dma_ch_idx] = (uint32_t) (this->mXres * this->mYres);
1296 win_idx = (win_idx == mFirstFb) ? (win_idx + 1) : win_idx;
1297#ifdef USE_FB_PHY_LINEAR
1298 windows_left = 1;
1299#ifdef G2D_COMPOSITION
1300 if (this->mG2dComposition)
1301 windows_left = NUM_HW_WIN_FB_PHY - 1;
1302#endif
1303#else
1304 windows_left = mHwc->hwc_ctrl.max_num_ovly - 1;
1305#endif
1306 if (reduceAvailableWindowCnt)
1307 windows_left = min(windows_left, mMaxWindowOverlapCnt - 1);
1308 rects[dma_ch_idx].push_back(fb_rect);
1309 if (addFB) {
1310 addFB = false;
1311 mHwc->totPixels += mXres * mYres;
1312 }
1313 }
1314 else {
1315#ifdef USE_FB_PHY_LINEAR
1316 windows_left = 1;
1317#ifdef G2D_COMPOSITION
1318 if (this->mG2dComposition)
1319 windows_left = NUM_HW_WIN_FB_PHY;
1320#endif
1321#else
1322 windows_left = mHwc->hwc_ctrl.max_num_ovly;
1323#endif
1324 if (reduceAvailableWindowCnt)
1325 windows_left = min(windows_left, mMaxWindowOverlapCnt);
1326 }
1327
1328 changed = false;
1329 mGscLayers = 0;
1330 mCurrentGscIndex = 0;
1331 mCurrentRGBMPPIndex = 0;
1332 bool switchingOTF = false;
1333 reduceAvailableWindowCnt = false;
1334 for (size_t i = 0; i < contents->numHwLayers; i++) {
1335 hwc_layer_1_t &layer = contents->hwLayers[i];
1336 if ((layer.flags & HWC_SKIP_LAYER) ||
1337 layer.compositionType == HWC_FRAMEBUFFER_TARGET)
1338 continue;
1339
1340 private_handle_t *handle = private_handle_t::dynamicCast(
1341 layer.handle);
1342
1343 if (!layer.planeAlpha)
1344 continue;
1345
1346 // we've already accounted for the framebuffer above
1347 if (layer.compositionType == HWC_FRAMEBUFFER)
1348 continue;
1349
1350 // only layer 0 can be HWC_BACKGROUND, so we can
1351 // unconditionally allow it without extra checks
1352 if (layer.compositionType == HWC_BACKGROUND) {
1353 windows_left--;
1354 continue;
1355 }
1356 dma_ch_idx = FIMD_DMA_CH_IDX[win_idx];
1357
1358 size_t pixels_needed = 0;
1359 if (getDrmMode(handle->flags) != SECURE_DRM)
1360 pixels_needed = getRequiredPixels(layer, mXres, mYres);
1361 else
1362 pixels_needed = WIDTH(layer.displayFrame) *
1363 HEIGHT(layer.displayFrame);
1364
1365 cannotComposeFlag = 0;
1366 bool can_compose = windows_left && (win_idx < NUM_HW_WINDOWS) &&
1367 ((pixel_used[dma_ch_idx] + pixels_needed) <=
1368 (uint32_t)this->mDmaChannelMaxBandwidth[dma_ch_idx]);
1369 if (windows_left <= 0 || (win_idx >= NUM_HW_WINDOWS))
1370 cannotComposeFlag |= eInsufficientWindow;
1371 if ((pixel_used[dma_ch_idx] + pixels_needed) > (uint32_t)this->mDmaChannelMaxBandwidth[dma_ch_idx])
1372 cannotComposeFlag |= eInsufficientBandwidth;
1373
1374 int gsc_index = getMPPForUHD(layer);
1375
1376 bool gsc_required = mMPPs[gsc_index]->isProcessingRequired(layer, handle->format);
1377 if (gsc_required) {
1378 if (mHasDrmSurface && getDrmMode(handle->flags) == NO_DRM && MAX_VIDEO_LAYERS == 1) {
1379 can_compose = false;
1380 cannotComposeFlag = eHasDRMVideo;
1381 }
1382 if (mGscLayers >= MAX_VIDEO_LAYERS) {
1383 can_compose = can_compose && !mGscUsed;
1384 if (mGscUsed)
1385 cannotComposeFlag |= eInsufficientMPP;
1386 }
1387 if (mHwc->hwc_ctrl.num_of_video_ovly <= mGscLayers) {
1388 can_compose = false;
1389 cannotComposeFlag |= eInsufficientMPP;
1390 }
1391 if (switchingOTF) {
1392 can_compose = false;
1393 cannotComposeFlag |= eSwitchingLocalPath;
1394 }
1395 if (mOtfMode == OTF_RUNNING && win_idx > 0)
1396 switchingOTF = true;
1397 if (multipleRGBScaling(handle->format)) {
1398 can_compose = false;
1399 cannotComposeFlag |= eRGBLayerDuringVideoPlayback;
1400 }
1401 }
1402
1403 // hwc_rect_t right and bottom values are normally exclusive;
1404 // the intersection logic is simpler if we make them inclusive
1405 hwc_rect_t visible_rect = layer.displayFrame;
1406 visible_rect.right--; visible_rect.bottom--;
1407
1408 if (can_compose) {
1409 switch (this->mDmaChannelMaxOverlapCount[dma_ch_idx]) {
1410 case 1: // It means, no layer overlap is allowed
1411 for (size_t j = 0; j < rects[dma_ch_idx].size(); j++)
1412 if (intersect(visible_rect, rects[dma_ch_idx].itemAt(j))) {
1413 can_compose = false;
1414 cannotComposeFlag |= eInsufficientOverlapCount;
1415 }
1416 break;
1417 case 2: //It means, upto 2 layer overlap is allowed.
1418 for (size_t j = 0; j < overlaps[dma_ch_idx].size(); j++)
1419 if (intersect(visible_rect, overlaps[dma_ch_idx].itemAt(j))) {
1420 can_compose = false;
1421 cannotComposeFlag |= eInsufficientOverlapCount;
1422 }
1423 break;
1424 default:
1425 break;
1426 }
1427 if (!can_compose)
1428 this->mBypassSkipStaticLayer = true;
1429 }
1430
1431 if (!can_compose) {
1432 if (getDrmMode(handle->flags) != NO_DRM) {
1433 mFirstFb = 1;
1434 changed = true;
1435 break;
1436 } else {
1437 layer.compositionType = HWC_FRAMEBUFFER;
1438 mLayerInfos[i]->compositionType = layer.compositionType;
1439 mLayerInfos[i]->mCheckOverlayFlag |= cannotComposeFlag;
1440 if (!mFbNeeded) {
1441 mFirstFb = mLastFb = i;
1442 mFbNeeded = true;
1443 }
1444 else {
1445 mFirstFb = min(i, mFirstFb);
1446 mLastFb = max(i, mLastFb);
1447 }
1448 changed = true;
1449 mFirstFb = min(mFirstFb, (size_t)NUM_HW_WINDOWS-1);
1450 mHwc->totPixels -= WIDTH(layer.displayFrame) * HEIGHT(layer.displayFrame);
1451 break;
1452 }
1453 }
1454
1455 for (size_t j = 0; j < rects[dma_ch_idx].size(); j++) {
1456 const hwc_rect_t &other_rect = rects[dma_ch_idx].itemAt(j);
1457 if (intersect(visible_rect, other_rect))
1458 overlaps[dma_ch_idx].push_back(intersection(visible_rect, other_rect));
1459 }
1460
1461 rects[dma_ch_idx].push_back(visible_rect);
1462 pixel_used[dma_ch_idx] += pixels_needed;
1463 win_idx++;
1464 win_idx = (win_idx == mFirstFb) ? (win_idx + 1) : win_idx;
1465 win_idx = min(win_idx, NUM_HW_WINDOWS - 1);
1466 windows_left--;
1467 if (gsc_required) {
1468 mGscUsed = true;
1469 mGscLayers++;
1470 }
1471
1472 if (intersect(visible_rect, windowIntersection)) {
1473 windowIntersection = intersection(visible_rect, windowIntersection);
1474 intersectionCnt++;
1475 } else {
1476 windowIntersection = {0, 0, 0, 0};
1477 intersectionCnt = 0;
1478 }
1479 }
1480 if (mFbNeeded && intersectionCnt != 0)
1481 intersectionCnt++;
1482 if (changed) {
1483 for (size_t i = mFirstFb; i < mLastFb; i++) {
1484 hwc_layer_1_t &layer = contents->hwLayers[i];
1485 if (layer.handle) {
1486 private_handle_t *handle = private_handle_t::dynamicCast(layer.handle);
1487 if (getDrmMode(handle->flags) == NO_DRM) {
1488 contents->hwLayers[i].compositionType = HWC_FRAMEBUFFER;
1489 mLayerInfos[i]->compositionType = contents->hwLayers[i].compositionType;
1490 mLayerInfos[i]->mCheckOverlayFlag |= eSandwitchedBetweenGLES;
1491 }
1492 }
1493 }
1494 }
1495 handleTotalBandwidthOverload(contents);
1496 if (intersectionCnt > mMaxWindowOverlapCnt) {
1497 HLOGD("Total Overlap Cnt(%d) > Max Overlap Cnt(%d)", intersectionCnt, mMaxWindowOverlapCnt);
1498 changed = true;
1499 reduceAvailableWindowCnt = true;
1500 }
1501 } while(changed);
1502
1503 if (mGscLayers == 0)
1504 mHwc->allowOTF = true;
1505
1506 if (mPopupPlayYuvContents) {
1507 mFbUpdateRegion.left = 0;
1508 mFbUpdateRegion.top = 0;
1509 mFbUpdateRegion.right = mXres;
1510 mFbUpdateRegion.bottom = mYres;
1511 return;
1512 }
1513
1514 for (size_t i = mFirstFb; i <= mLastFb; i++)
1515 mFbUpdateRegion = expand(mFbUpdateRegion, contents->hwLayers[i].displayFrame);
1516
1517 for (size_t i = mLastFb + 1; i < contents->numHwLayers; i++) {
1518 hwc_layer_1_t &layer = contents->hwLayers[i];
1519 if (layer.compositionType == HWC_OVERLAY && layer.planeAlpha > 0 && layer.planeAlpha < 255)
1520 mFbUpdateRegion = expand(mFbUpdateRegion, contents->hwLayers[i].displayFrame);
1521 }
1522
1523 int minWidth = BURSTLEN_BYTES * 8 / formatToBpp(HAL_PIXEL_FORMAT_RGBA_8888);
1524 int w = WIDTH(mFbUpdateRegion);
1525 if (w < minWidth) {
1526 if (mFbUpdateRegion.left + minWidth <= mXres)
1527 mFbUpdateRegion.right = mFbUpdateRegion.left + minWidth;
1528 else
1529 mFbUpdateRegion.left = mFbUpdateRegion.right - minWidth;
1530 }
1531}
1532
1533void ExynosOverlayDisplay::assignWindows(hwc_display_contents_1_t *contents)
1534{
1535 unsigned int nextWindow = 0;
1536
1537 for (size_t i = 0; i < contents->numHwLayers; i++) {
1538 hwc_layer_1_t &layer = contents->hwLayers[i];
1539
1540 if (!layer.planeAlpha)
1541 continue;
1542
1543 if (!mPopupPlayYuvContents) {
1544 if (mFbNeeded && i == mFirstFb) {
1545 ALOGV("assigning framebuffer to window %u\n",
1546 nextWindow);
1547 mPostData.fb_window = nextWindow;
1548 nextWindow++;
1549 continue;
1550 }
1551 }
1552
1553 if (layer.handle) {
1554 private_handle_t *handle = private_handle_t::dynamicCast(layer.handle);
1555 if (ExynosMPP::isFormatSupportedByGscOtf(handle->format)) {
1556 /* in case of changing compostiontype form GSC to FRAMEBUFFER for yuv layer */
1557 if ((mConfigMode == 1) && (layer.compositionType == HWC_FRAMEBUFFER)) {
1558 mForceFbYuvLayer = 1;
1559 mConfigMode = 0;
1560 mCountSameConfig = 0;
1561 /* for prepare */
1562 mForceFb = 1;
1563 mRetry = true;
1564 return;
1565 }
1566 }
1567 }
1568 if (layer.compositionType != HWC_FRAMEBUFFER &&
1569 layer.compositionType != HWC_FRAMEBUFFER_TARGET) {
1570 ALOGV("assigning layer %u to window %u", i, nextWindow);
1571 this->mPostData.overlay_map[nextWindow] = i;
1572 if (layer.compositionType == HWC_OVERLAY) {
1573 private_handle_t *handle =
1574 private_handle_t::dynamicCast(layer.handle);
1575 if (mMPPs[0]->isProcessingRequired(layer, handle->format)) {
1576 if (assignGscLayer(layer, i, nextWindow))
1577 mCurrentGscIndex++;
1578 }
1579 }
1580 nextWindow++;
1581 }
1582 }
1583}
1584
1585bool ExynosOverlayDisplay::assignGscLayer(hwc_layer_1_t &layer, int index, int nextWindow)
1586{
1587 private_handle_t *handle = private_handle_t::dynamicCast(layer.handle);
1588 size_t gscIndex = 0;
1589 int downNumerator, downDenominator;
1590 int downError = mMPPs[0]->getDownscaleRatio(&downNumerator, &downDenominator);
1591 bool ret = true;
1592 if (nextWindow == 0 &&
1593 !(handle->flags & GRALLOC_USAGE_HW_CAMERA_MASK) &&
1594 !downError &&
1595 (mMPPs[0]->isProcessingSupported(layer, handle->format, true, downNumerator, downDenominator) > 0)) {
1596 gscIndex = mCurrentGscIndex;
1597 ALOGV("\tusing gscaler %u in LOCAL-PATH", AVAILABLE_GSC_UNITS[gscIndex]);
1598 if (!mMPPs[gscIndex]->isOTF())
1599 mMPPs[gscIndex]->cleanupM2M(true);
1600 mPostData.gsc_map[nextWindow].mode = exynos5_gsc_map_t::GSC_LOCAL;
1601 mMPPs[gscIndex]->setMode(exynos5_gsc_map_t::GSC_LOCAL);
1602 mPostData.gsc_map[nextWindow].idx = FIMD_GSC_IDX;
1603 if (mOtfMode == OTF_OFF)
1604 mOtfMode = OTF_RUNNING;
1605 mMPPs[0]->mNeedReqbufs = false;
1606 } else {
1607 gscIndex = getMPPForUHD(layer);
1608 if (gscIndex == FIMD_GSC_IDX) {
1609 gscIndex = mCurrentGscIndex;
1610 ret = true;
1611 } else {
1612 ret = false;
1613 }
1614 if (isFormatRgb(handle->format)) {
1615 gscIndex = getRGBMPPIndex(mCurrentRGBMPPIndex);
1616 if (gscIndex != FIMD_GSC_IDX && gscIndex != FIMD_GSC_SEC_IDX)
1617 mCurrentRGBMPPIndex++;
1618 }
1619 ALOGV("\tusing gscaler %u in M2M", AVAILABLE_GSC_UNITS[gscIndex]);
1620 mPostData.gsc_map[nextWindow].mode = exynos5_gsc_map_t::GSC_M2M;
1621 mMPPs[gscIndex]->setMode(exynos5_gsc_map_t::GSC_M2M);
1622 mPostData.gsc_map[nextWindow].idx = gscIndex;
1623 if ((gscIndex == FIMD_GSC_IDX || (mMPPs[gscIndex]->isUsingMSC() && mCurrentGscIndex == 0)) && mOtfMode == OTF_RUNNING) {
1624 ALOGV("change from OTF to M2M");
1625 mOtfMode = OTF_TO_M2M;
1626 if (mMPPs[gscIndex]->isUsingMSC()) {
1627 mMPPs[0]->setMode(exynos5_gsc_map_t::GSC_LOCAL);
1628 } else {
1629 mMPPs[gscIndex]->setMode(exynos5_gsc_map_t::GSC_LOCAL);
1630 mMPPs[FIMD_GSC_SEC_IDX]->setMode(exynos5_gsc_map_t::GSC_M2M);
1631 mPostData.gsc_map[nextWindow].idx = FIMD_GSC_SEC_IDX;
1632 }
1633 }
1634 }
1635 ALOGV("\tusing gscaler %u",
1636 AVAILABLE_GSC_UNITS[gscIndex]);
1637 return ret;
1638}
1639
1640int ExynosOverlayDisplay::waitForRenderFinish(buffer_handle_t *handle, int buffers)
1641{
1642 return 0;
1643}
1644
1645int ExynosOverlayDisplay::postGscM2M(hwc_layer_1_t &layer, struct s3c_fb_win_config *config, int win_map, int index, bool isBottom)
1646{
1647 exynos5_hwc_post_data_t *pdata = &mPostData;
1648 int gsc_idx = pdata->gsc_map[index].idx;
1649 int dst_format = HAL_PIXEL_FORMAT_RGBX_8888;
1650 private_handle_t *handle = private_handle_t::dynamicCast(layer.handle);
1651 int32_t deconBlending = HWC_BLENDING_NONE;
1652 int32_t originalBlending = HWC_BLENDING_NONE;
1653
1654 hwc_frect_t sourceCrop = { 0, 0,
1655 (float)WIDTH(layer.displayFrame), (float)HEIGHT(layer.displayFrame) };
1656 if (mHwc->mS3DMode == S3D_MODE_READY || mHwc->mS3DMode == S3D_MODE_RUNNING) {
1657 int S3DFormat = getS3DFormat(mHwc->mHdmiPreset);
1658 if (S3DFormat == S3D_SBS)
1659 mMPPs[gsc_idx]->mS3DMode = S3D_SBS;
1660 else if (S3DFormat == S3D_TB)
1661 mMPPs[gsc_idx]->mS3DMode = S3D_TB;
1662 } else {
1663 mMPPs[gsc_idx]->mS3DMode = S3D_NONE;
1664 }
1665
1666 if (isFormatRgb(handle->format))
1667 waitForRenderFinish(&layer.handle, 1);
1668 /* OFF_Screen to ON_Screen changes */
1669 if (getDrmMode(handle->flags) == SECURE_DRM)
1670 recalculateDisplayFrame(layer, mXres, mYres);
1671
1672 if (handle->format == HAL_PIXEL_FORMAT_RGB_565)
1673 dst_format = HAL_PIXEL_FORMAT_RGB_565;
1674
1675 if (isBottom) {
1676 originalBlending = layer.blending;
1677 layer.blending = HWC_BLENDING_NONE;
1678 }
1679
1680 int err = mMPPs[gsc_idx]->processM2M(layer, dst_format, &sourceCrop);
1681
1682 if (isBottom)
1683 layer.blending = originalBlending;
1684
1685 if (err < 0) {
1686 ALOGE("failed to configure gscaler %u for layer %u",
1687 gsc_idx, index);
1688 pdata->gsc_map[index].mode = exynos5_gsc_map_t::GSC_NONE;
1689 return -1;
1690 }
1691
1692 buffer_handle_t dst_buf = mMPPs[gsc_idx]->mDstBuffers[mMPPs[gsc_idx]->mCurrentBuf];
1693 private_handle_t *dst_handle =
1694 private_handle_t::dynamicCast(dst_buf);
1695 int prevFormat = -1;
1696 if (((handle->format == HAL_PIXEL_FORMAT_RGBA_8888) || (handle->format == HAL_PIXEL_FORMAT_RGBX_8888) || (handle->format == HAL_PIXEL_FORMAT_RGB_565))
1697 && dst_handle->format == HAL_PIXEL_FORMAT_BGRA_8888) {
1698 prevFormat = dst_handle->format;
1699 dst_handle->format = handle->format;
1700 }
1701 int fence = mMPPs[gsc_idx]->mDstConfig.releaseFenceFd;
1702
1703 if (layer.blending == HWC_BLENDING_PREMULT)
1704 deconBlending = HWC_BLENDING_COVERAGE;
1705 else
1706 deconBlending = layer.blending;
1707
1708 configureHandle(dst_handle, sourceCrop,
1709 layer.displayFrame, deconBlending, layer.planeAlpha, fence,
1710 config[win_map]);
1711
1712#ifdef USES_DRM_SETTING_BY_DECON
1713 if (getDrmMode(handle->flags) != NO_DRM)
1714 config[win_map].protection = 1;
1715 else
1716 config[win_map].protection = 0;
1717#endif
1718
1719 if (prevFormat >= 0)
1720 dst_handle->format = prevFormat;
1721 return 0;
1722}
1723
1724void ExynosOverlayDisplay::postGscOtf(hwc_layer_1_t &layer, struct s3c_fb_win_config *config, int win_map, int index)
1725{
1726#ifdef USES_DRM_SETTING_BY_DECON
1727 private_handle_t *handle = private_handle_t::dynamicCast(layer.handle);
1728#endif
1729 exynos5_hwc_post_data_t *pdata = &mPostData;
1730 int gsc_idx = pdata->gsc_map[index].idx;
1731 if (mHwc->mS3DMode == S3D_MODE_READY || mHwc->mS3DMode == S3D_MODE_RUNNING) {
1732 int S3DFormat = getS3DFormat(mHwc->mHdmiPreset);
1733 if (S3DFormat == S3D_SBS)
1734 mMPPs[gsc_idx]->mS3DMode = S3D_SBS;
1735 else if (S3DFormat == S3D_TB)
1736 mMPPs[gsc_idx]->mS3DMode = S3D_TB;
1737 } else {
1738 mMPPs[gsc_idx]->mS3DMode = S3D_NONE;
1739 }
1740
1741 int err = mMPPs[gsc_idx]->processOTF(layer);
1742
1743 if (err < 0) {
1744 ALOGE("failed to config_gsc_localout %u input for layer %u", gsc_idx, index);
1745 mOtfMode = OTF_TO_M2M;
1746 configureDummyOverlay(&layer, config[win_map]);
1747 } else {
1748 configureOtfWindow(layer.displayFrame, layer.blending, layer.planeAlpha,
1749 layer.acquireFenceFd, HAL_PIXEL_FORMAT_RGBX_8888, config[win_map]);
1750 }
1751#ifdef USES_DRM_SETTING_BY_DECON
1752 if (getDrmMode(handle->flags) != NO_DRM)
1753 config[win_map].protection = 1;
1754 else
1755 config[win_map].protection = 0;
1756#endif
1757 return;
1758}
1759
1760void ExynosOverlayDisplay::handleStaticLayers(hwc_display_contents_1_t *contents, struct s3c_fb_win_config_data &win_data, int tot_ovly_wins)
1761{
1762 int win_map = 0;
1763 if (mLastFbWindow >= NUM_HW_WINDOWS) {
1764 ALOGE("handleStaticLayers:: invalid mLastFbWindow(%d)", mLastFbWindow);
1765 return;
1766 }
1767 win_map = getDeconWinMap(mLastFbWindow, tot_ovly_wins);
1768 ALOGV("[USE] SKIP_STATIC_LAYER_COMP, mLastFbWindow(%d), win_map(%d)\n", mLastFbWindow, win_map);
1769
1770 memcpy(&win_data.config[win_map],
1771 &mLastConfigData.config[win_map], sizeof(struct s3c_fb_win_config));
1772 win_data.config[win_map].fence_fd = -1;
1773
1774 for (size_t i = mFirstFb; i <= mLastFb; i++) {
1775 hwc_layer_1_t &layer = contents->hwLayers[i];
1776 if (layer.compositionType == HWC_OVERLAY) {
1777 ALOGV("[SKIP_STATIC_LAYER_COMP] layer.handle: 0x%p, layer.acquireFenceFd: %d\n", layer.handle, layer.acquireFenceFd);
1778 layer.releaseFenceFd = layer.acquireFenceFd;
1779 }
1780 }
1781}
1782
1783int ExynosOverlayDisplay::getMPPForUHD(hwc_layer_1_t &layer)
1784{
1785 return FIMD_GSC_IDX;
1786}
1787
1788void ExynosOverlayDisplay::cleanupGscs()
1789{
1790 if (mMPPs[FIMD_GSC_IDX]->isM2M()) {
1791 mMPPs[FIMD_GSC_IDX]->cleanupM2M();
1792 mMPPs[FIMD_GSC_IDX]->setMode(exynos5_gsc_map_t::GSC_NONE);
1793 } else if (mMPPs[FIMD_GSC_IDX]->isOTF()) {
1794 mMPPs[FIMD_GSC_IDX]->cleanupOTF();
1795 } else if (mMPPs[FIMD_GSC_SEC_IDX]->isM2M()) {
1796 mMPPs[FIMD_GSC_SEC_IDX]->cleanupM2M();
1797 mMPPs[FIMD_GSC_SEC_IDX]->setMode(exynos5_gsc_map_t::GSC_NONE);
1798 }
1799 for (int i = FIMD_GSC_SEC_IDX + 1; i < mNumMPPs; i++) {
1800 if (mMPPs[i]->isM2M()) {
1801 mMPPs[i]->cleanupM2M();
1802 mMPPs[i]->setMode(exynos5_gsc_map_t::GSC_NONE);
1803 }
1804 }
1805}
1806
1807void ExynosOverlayDisplay::freeMPP()
1808{
1809 bool invalidate = false;
1810 for (int i = 0; i < mNumMPPs; i++) {
1811 if (mMPPs[i]->needsReqbufs()) {
1812 mMPPs[i]->free();
1813 invalidate = true;
1814 }
1815 }
1816 if (invalidate)
1817 mHwc->procs->invalidate(mHwc->procs);
1818}
1819
1820void ExynosOverlayDisplay::refreshGscUsage(hwc_layer_1_t &layer)
1821{
1822 private_handle_t *handle = private_handle_t::dynamicCast(layer.handle);
1823 int gsc_index = getMPPForUHD(layer);
1824 bool gsc_required = mMPPs[gsc_index]->isProcessingRequired(layer, handle->format);
1825 if (gsc_required) {
1826 if (mGscLayers >= 1)
1827 mGscLayers--;
1828 else
1829 ALOGW("refreshGscUsage: GSC layer count is invalid");
1830 if (!mGscLayers)
1831 mGscUsed = false;
1832 }
1833}
1834
1835void ExynosOverlayDisplay::handleTotalBandwidthOverload(hwc_display_contents_1_t *contents)
1836{
1837 if (mHwc->totPixels >= FIMD_TOTAL_BW_LIMIT) {
1838 if (mFbNeeded) {
1839 for (int i = mFirstFb - 1; i >= 0; i--) {
1840 if (mForceOverlayLayerIndex == 0 && i == 0)
1841 break;
1842 hwc_layer_1_t &layer = contents->hwLayers[i];
1843 refreshGscUsage(layer);
1844 layer.compositionType = HWC_FRAMEBUFFER;
1845 mLayerInfos[i]->compositionType = layer.compositionType;
1846 mLayerInfos[i]->mCheckOverlayFlag |= eInsufficientBandwidth;
1847 mFirstFb = i;
1848 mHwc->totPixels -= WIDTH(layer.displayFrame) * HEIGHT(layer.displayFrame);
1849 if (mHwc->totPixels < FIMD_TOTAL_BW_LIMIT)
1850 break;
1851 }
1852 if (mHwc->totPixels >= FIMD_TOTAL_BW_LIMIT) {
1853 for (int i = mLastFb + 1; i < contents->numHwLayers - 1; i++) {
1854 hwc_layer_1_t &layer = contents->hwLayers[i];
1855 refreshGscUsage(layer);
1856 layer.compositionType = HWC_FRAMEBUFFER;
1857 mLayerInfos[i]->compositionType = layer.compositionType;
1858 mLayerInfos[i]->mCheckOverlayFlag |= eInsufficientBandwidth;
1859 mLastFb = i;
1860 mHwc->totPixels -= WIDTH(layer.displayFrame) * HEIGHT(layer.displayFrame);
1861 if (mHwc->totPixels < FIMD_TOTAL_BW_LIMIT)
1862 break;
1863 }
1864 }
1865 } else {
1866 bool fbAdded = false;
1867 for (size_t i = 0; i < contents->numHwLayers; i++) {
1868 hwc_layer_1_t &layer = contents->hwLayers[i];
1869 if (layer.compositionType == HWC_OVERLAY &&
1870 mForceOverlayLayerIndex != i) {
1871 refreshGscUsage(layer);
1872 layer.compositionType = HWC_FRAMEBUFFER;
1873 mLastFb = max(mLastFb, i);
1874 mLayerInfos[i]->compositionType = layer.compositionType;
1875 mLayerInfos[i]->mCheckOverlayFlag |= eInsufficientBandwidth;
1876
1877 if (!fbAdded) {
1878 fbAdded = true;
1879 mHwc->totPixels += mXres * mYres;
1880 }
1881 if (mHwc->totPixels < FIMD_TOTAL_BW_LIMIT)
1882 break;
1883 }
1884 }
1885 if (mPopupPlayYuvContents || mForceOverlayLayerIndex == 0)
1886 mFirstFb = 1;
1887 else
1888 mFirstFb = 0;
1889 }
1890 mFbNeeded = true;
1891 }
1892}
1893
1894bool ExynosOverlayDisplay::switchOTF(bool enable)
1895{
1896 bool ret;
1897 if (mGscLayers > 1)
1898 return false;
1899 ret = mHwc->allowOTF != enable;
1900 mHwc->allowOTF = enable;
1901 return ret;
1902}
1903
1904int ExynosOverlayDisplay::getRGBMPPIndex(int index)
1905{
1906 return index;
1907}
1908
1909bool ExynosOverlayDisplay::multipleRGBScaling(int format)
1910{
1911 return isFormatRgb(format) &&
1912 mGscLayers >= 1;
1913}
1914
1915void ExynosOverlayDisplay::checkTVBandwidth()
1916{
1917}
1918
1919void ExynosOverlayDisplay::dump(android::String8& result)
1920{
1921 result.append(
1922 " type | handle | color | blend | pa | format | position | size | gsc \n"
1923 "----------+----------|----------+-------+----|----------+---------------+---------------------\n");
1924 // 8_______ | 8_______ | 8_______ | 5____ | 2_ | 8_______ | [5____,5____] | [5____,5____] | 3__ \n"
1925
1926 int windowsUsed = 0;
1927 for (size_t i = 0; i < NUM_HW_WINDOWS; i++) {
1928 struct s3c_fb_win_config &config = mLastConfigData.config[i];
1929 if (config.state != config.S3C_FB_WIN_STATE_DISABLED)
1930 windowsUsed++;
1931 }
1932
1933 for (size_t i = 0; i < NUM_HW_WINDOWS; i++) {
1934 struct s3c_fb_win_config &config = mLastConfigData.config[i];
1935 size_t inverse = inverseWinMap(i, windowsUsed);
1936 if ((config.state == config.S3C_FB_WIN_STATE_DISABLED) &&
1937 (mLastGscMap[inverse].mode == exynos5_gsc_map_t::GSC_NONE)){
1938 result.appendFormat(" %8s | %8s | %8s | %5s | %2s | %8s | %13s | %13s",
1939 "OVERLAY", "-", "-", "-", "-", "-", "-", "-");
1940 }
1941 else {
1942 if (config.state == config.S3C_FB_WIN_STATE_COLOR)
1943 result.appendFormat(" %8s | %8s | %8x | %5s | %2s | %8s", "COLOR",
1944 "-", config.color, "-", "-", "-");
1945 else
1946 result.appendFormat(" %8s | %8x | %8s | %5x | %2x | %8s",
1947 mLastFbWindow == inverse ? "FB" : "OVERLAY",
1948 intptr_t(mLastHandles[i]),
1949 "-", config.blending, config.plane_alpha, s3cFormat2str(config.format));
1950
1951 result.appendFormat(" | [%5d,%5d] | [%5u,%5u]", config.x, config.y,
1952 config.w, config.h);
1953 }
1954 if (mLastGscMap[inverse].mode == exynos5_gsc_map_t::GSC_NONE) {
1955 result.appendFormat(" | %3s", "-");
1956 } else {
1957 result.appendFormat(" | %3d",
1958 AVAILABLE_GSC_UNITS[mLastGscMap[inverse].idx]);
1959 if (mLastGscMap[inverse].mode == exynos5_gsc_map_t::GSC_M2M)
1960 result.appendFormat(" | %10s","GSC_M2M");
1961 else
1962 result.appendFormat(" | %10s","GSC_LOCAL");
1963 }
1964 result.append("\n");
1965 }
1966}
1967
1968unsigned int ExynosOverlayDisplay::getLayerRegion(hwc_layer_1_t &layer, hwc_rect &rect_area, uint32_t regionType) {
1969 hwc_rect_t const *hwcRects = NULL;
1970 unsigned int numRects = 0;
1971
1972 switch (regionType) {
1973 case eDamageRegion:
1974 hwcRects = layer.surfaceDamage.rects;
1975 numRects = layer.surfaceDamage.numRects;
1976 break;
1977 default:
1978 ALOGE("%s:: Invalid regionType (%d)", __func__, regionType);
1979 return eDamageRegionError;
1980 }
1981 if ((numRects == 0) || (hwcRects == NULL))
1982 return eDamageRegionFull;
1983
1984 if ((numRects == 1) && (hwcRects[0].left == 0) && (hwcRects[0].top == 0) &&
1985 (hwcRects[0].right == 0) && (hwcRects[0].bottom == 0))
1986 return eDamageRegionSkip;
1987
1988 rect_area.left = INT_MAX;
1989 rect_area.top = INT_MAX;
1990 rect_area.right = rect_area.bottom = 0;
1991 if (hwcRects != NULL) {
1992 for (size_t j = 0; j < numRects; j++) {
1993 hwc_rect_t rect;
1994 rect.left = hwcRects[j].left;
1995 rect.top = hwcRects[j].top;
1996 rect.right = hwcRects[j].right;
1997 rect.bottom = hwcRects[j].bottom;
1998 adjustRect(rect, INT_MAX, INT_MAX);
1999 /* Get sums of rects */
2000 rect_area = expand(rect_area, rect);
2001 }
2002 }
2003
2004 return eDamageRegionPartial;
2005}