libhwcutils: resolve compilation errors
[GitHub/LineageOS/android_hardware_samsung_slsi_exynos.git] / libhwcutils / ExynosMPP.cpp
1 #define ATRACE_TAG ATRACE_TAG_GRAPHICS
2
3 #include <utils/Trace.h>
4 #include "ExynosMPP.h"
5 #include "ExynosHWCUtils.h"
6 #ifdef USES_VIRTUAL_DISPLAY
7 #include "ExynosVirtualDisplay.h"
8 #endif
9
10 size_t visibleWidth(ExynosMPP *processor, hwc_layer_1_t &layer, int format,
11 int xres)
12 {
13 int bpp;
14 if (processor->isProcessingRequired(layer, format) && format != HAL_PIXEL_FORMAT_RGB_565)
15 bpp = 32;
16 else
17 bpp = formatToBpp(format);
18 int left = max(layer.displayFrame.left, 0);
19 int right = min(layer.displayFrame.right, xres);
20
21 return (right - left) * bpp / 8;
22 }
23
24 ExynosMPP::ExynosMPP()
25 {
26 ExynosMPP(NULL, 0);
27 }
28
29 ExynosMPP::ExynosMPP(ExynosDisplay *display, int gscIndex)
30 {
31 ATRACE_CALL();
32 this->mDisplay = display;
33 this->mIndex = gscIndex;
34 mNeedReqbufs = false;
35 mWaitVsyncCount = 0;
36 mCountSameConfig = 0;
37 mGscHandle = NULL;
38 memset(&mSrcConfig, 0, sizeof(mSrcConfig));
39 memset(&mMidConfig, 0, sizeof(mMidConfig));
40 memset(&mDstConfig, 0, sizeof(mDstConfig));
41 for (size_t i = 0; i < NUM_GSC_DST_BUFS; i++) {
42 mDstBuffers[i] = NULL;
43 mMidBuffers[i] = NULL;
44 mDstBufFence[i] = -1;
45 mMidBufFence[i] = -1;
46 }
47 mNumAvailableDstBuffers = NUM_GSC_DST_BUFS;
48 mCurrentBuf = 0;
49 mGSCMode = 0;
50 mLastGSCLayerHandle = -1;
51 mS3DMode = 0;
52 mppFact = NULL;
53 libmpp = NULL;
54 mDoubleOperation = false;
55 mBufferFreeThread = new BufferFreeThread(this);
56 mBufferFreeThread->mRunning = true;
57 mBufferFreeThread->run("MPPThread");
58 }
59
60 ExynosMPP::~ExynosMPP()
61 {
62 if (mBufferFreeThread != NULL) {
63 mBufferFreeThread->mRunning = false;
64 mBufferFreeThread->requestExitAndWait();
65 delete mBufferFreeThread;
66 }
67 }
68
69 bool ExynosMPP::isM2M()
70 {
71 return mGSCMode == exynos5_gsc_map_t::GSC_M2M;
72 }
73
74 bool ExynosMPP::isUsingMSC()
75 {
76 return (AVAILABLE_GSC_UNITS[mIndex] >= 4 && AVAILABLE_GSC_UNITS[mIndex] <= 6);
77 }
78
79 bool ExynosMPP::isOTF()
80 {
81 return mGSCMode == exynos5_gsc_map_t::GSC_LOCAL;
82 }
83
84 void ExynosMPP::setMode(int mode)
85 {
86 mGSCMode = mode;
87 }
88
89 void ExynosMPP::free()
90 {
91 if (mNeedReqbufs) {
92 if (mWaitVsyncCount > 0) {
93 if (mGscHandle)
94 freeMPP(mGscHandle);
95 mNeedReqbufs = false;
96 mWaitVsyncCount = 0;
97 mDisplay->mOtfMode = OTF_OFF;
98 mGscHandle = NULL;
99 libmpp = NULL;
100 memset(&mSrcConfig, 0, sizeof(mSrcConfig));
101 memset(&mMidConfig, 0, sizeof(mMidConfig));
102 memset(&mDstConfig, 0, sizeof(mDstConfig));
103 memset(mDstBuffers, 0, sizeof(mDstBuffers));
104 memset(mMidBuffers, 0, sizeof(mMidBuffers));
105 mCurrentBuf = 0;
106 mGSCMode = 0;
107 mLastGSCLayerHandle = 0;
108
109 for (size_t i = 0; i < NUM_GSC_DST_BUFS; i++) {
110 mDstBufFence[i] = -1;
111 mMidBufFence[i] = -1;
112 }
113 } else {
114 mWaitVsyncCount++;
115 }
116 }
117 }
118
119 bool ExynosMPP::isSrcConfigChanged(exynos_mpp_img &c1, exynos_mpp_img &c2)
120 {
121 return isDstConfigChanged(c1, c2) ||
122 c1.fw != c2.fw ||
123 c1.fh != c2.fh;
124 }
125
126 bool ExynosMPP::isFormatSupportedByGsc(int format)
127 {
128
129 switch (format) {
130 case HAL_PIXEL_FORMAT_RGBA_8888:
131 case HAL_PIXEL_FORMAT_RGBX_8888:
132 case HAL_PIXEL_FORMAT_RGB_565:
133 case HAL_PIXEL_FORMAT_EXYNOS_YV12_M:
134 case HAL_PIXEL_FORMAT_YV12:
135 case HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_P_M:
136 case HAL_PIXEL_FORMAT_EXYNOS_YCrCb_420_SP_M:
137 case HAL_PIXEL_FORMAT_EXYNOS_YCrCb_420_SP_M_FULL:
138 case HAL_PIXEL_FORMAT_YCrCb_420_SP:
139 case HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SP_M:
140 case HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SP_M_PRIV:
141 case HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SP_M_TILED:
142 return true;
143
144 default:
145 return false;
146 }
147 }
148
149 bool ExynosMPP::formatRequiresGsc(int format)
150 {
151 return (isFormatSupportedByGsc(format) &&
152 (format != HAL_PIXEL_FORMAT_RGBX_8888) && (format != HAL_PIXEL_FORMAT_RGB_565) &&
153 (format != HAL_PIXEL_FORMAT_RGBA_8888));
154 }
155
156 int ExynosMPP::getDownscaleRatio(int *downNumerator, int *downDenominator)
157 {
158 *downNumerator = 0;
159 *downDenominator = 0;
160 return -1;
161 }
162
163 bool ExynosMPP::isFormatSupportedByGscOtf(int format)
164 {
165 switch (format) {
166 case HAL_PIXEL_FORMAT_RGBA_8888:
167 case HAL_PIXEL_FORMAT_RGBX_8888:
168 case HAL_PIXEL_FORMAT_RGB_565:
169 case HAL_PIXEL_FORMAT_EXYNOS_YV12_M:
170 case HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_P_M:
171 case HAL_PIXEL_FORMAT_EXYNOS_YCrCb_420_SP_M:
172 case HAL_PIXEL_FORMAT_EXYNOS_YCrCb_420_SP_M_FULL:
173 case HAL_PIXEL_FORMAT_YCrCb_420_SP:
174 case HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SP_M:
175 case HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SP_M_PRIV:
176 case HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SP_M_TILED:
177 return true;
178 default:
179 return false;
180 }
181 }
182
183 int ExynosMPP::isProcessingSupported(hwc_layer_1_t &layer, int format,
184 bool local_path, int downNumerator, int downDenominator)
185 {
186 if (local_path && downNumerator == 0) {
187 return -eMPPUnsupportedDownScale;
188 }
189
190 if (isUsingMSC() && local_path) {
191 return -eMPPUnsupportedHW;
192 }
193
194 if (!isUsingMSC() && layer.blending != HWC_BLENDING_NONE)
195 return -eMPPUnsupportedBlending;
196
197 private_handle_t *handle = private_handle_t::dynamicCast(layer.handle);
198
199 if (isUsingMSC() && handle &&
200 isFormatRgb(handle->format) && !hasAlpha(handle->format) &&
201 (layer.blending == HWC_BLENDING_PREMULT))
202 return -eMPPUnsupportedBlending;
203
204 int max_w = maxWidth(layer);
205 int max_h = maxHeight(layer);
206 int min_w = minWidth(layer);
207 int min_h = minHeight(layer);
208 int crop_max_w = 0;
209 int crop_max_h = 0;
210 int dest_min_h = 0;
211
212 if (isUsingMSC()) {
213 crop_max_w = 8192;
214 crop_max_h = 8192;
215 } else {
216 crop_max_w = isRotated(layer) ? 2016 : 4800;
217 crop_max_h = isRotated(layer) ? 2016 : 3344;
218 }
219 int crop_min_w = isRotated(layer) ? 32: 64;
220 int crop_min_h = isRotated(layer) ? 64: 32;
221
222 if (local_path)
223 dest_min_h = 64;
224 else
225 dest_min_h = 32;
226
227 int srcWidthAlign = sourceWidthAlign(handle->format);
228 int srcHeightAlign = sourceHeightAlign(handle->format);
229 int dstAlign;
230 if (local_path)
231 dstAlign = destinationAlign(HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SP_M);
232 else
233 dstAlign = destinationAlign(HAL_PIXEL_FORMAT_BGRA_8888);
234
235 int maxDstWidth;
236 int maxDstHeight;
237
238 bool rot90or270 = !!(layer.transform & HAL_TRANSFORM_ROT_90);
239 // n.b.: HAL_TRANSFORM_ROT_270 = HAL_TRANSFORM_ROT_90 |
240 // HAL_TRANSFORM_ROT_180
241
242 int src_w = WIDTH(layer.sourceCropf), src_h = HEIGHT(layer.sourceCropf);
243 if (!isUsingMSC()) {
244 src_w = getAdjustedCrop(src_w, WIDTH(layer.displayFrame), handle->format, false, rot90or270);
245 src_h = getAdjustedCrop(src_h, HEIGHT(layer.displayFrame), handle->format, true, rot90or270);
246 }
247 int dest_w, dest_h;
248 if (rot90or270) {
249 dest_w = HEIGHT(layer.displayFrame);
250 dest_h = WIDTH(layer.displayFrame);
251 } else {
252 dest_w = WIDTH(layer.displayFrame);
253 dest_h = HEIGHT(layer.displayFrame);
254 }
255
256 if (getDrmMode(handle->flags) != NO_DRM)
257 alignCropAndCenter(dest_w, dest_h, NULL,
258 GSC_DST_CROP_W_ALIGNMENT_RGB888);
259
260 maxDstWidth = 2560;
261 maxDstHeight = 2560;
262 int max_upscale = 8;
263
264 /* check whether GSC can handle with local path */
265 if (local_path) {
266 if (isFormatRgb(format) && rot90or270)
267 return -eMPPUnsupportedRotation;
268
269 /* GSC OTF can't handle rot90 or rot270 */
270 if (!rotationSupported(rot90or270))
271 return -eMPPUnsupportedRotation;
272 /*
273 * if display co-ordinates are out of the lcd resolution,
274 * skip that scenario to OpenGL.
275 * GSC OTF can't handle such scenarios.
276 */
277 if (layer.displayFrame.left < 0 || layer.displayFrame.top < 0 ||
278 layer.displayFrame.right > mDisplay->mXres || layer.displayFrame.bottom > mDisplay->mYres)
279 return -eMPPUnsupportedCoordinate;
280
281 /* GSC OTF can't handle GRALLOC_USAGE_PROTECTED layer */
282 if (getDrmMode(handle->flags) != NO_DRM)
283 return -eMPPUnsupportedDRMContents;
284
285 if (!isFormatSupportedByGsc(format))
286 return -eMPPUnsupportedFormat;
287 else if (!isFormatSupportedByGscOtf(format))
288 return -eMPPUnsupportedFormat;
289 else if (format == HAL_PIXEL_FORMAT_RGBA_8888 && layer.blending != HWC_BLENDING_NONE)
290 return -eMPPUnsupportedBlending;
291 else if (mDisplay->mHwc->mS3DMode != S3D_MODE_DISABLED)
292 return -eMPPUnsupportedS3DContents;
293 else if (!paritySupported(dest_w, dest_h))
294 return -eMPPNotAlignedDstSize;
295 else if (handle->stride > max_w)
296 return -eMPPExceedHStrideMaximum;
297 else if (src_w * downNumerator > dest_w * downDenominator)
298 return -eMPPExeedMaxDownScale;
299 else if (dest_w > maxDstWidth)
300 return -eMPPExeedMaxDstWidth;
301 else if (dest_w > src_w * max_upscale)
302 return -eMPPExeedMaxUpScale;
303 else if (handle->vstride > max_h)
304 return -eMPPExceedVStrideMaximum;
305 else if (src_h * downNumerator > dest_h * downDenominator)
306 return -eMPPExeedMaxDownScale;
307 else if (dest_h > maxDstHeight)
308 return -eMPPExeedMaxDstHeight;
309 else if (dest_h > src_h * max_upscale)
310 return -eMPPExeedMaxUpScale;
311 else if (src_w > crop_max_w)
312 return -eMPPExeedSrcWCropMax;
313 else if (src_h > crop_max_h)
314 return -eMPPExeedSrcHCropMax;
315 else if (src_w < crop_min_w)
316 return -eMPPExeedSrcWCropMin;
317 else if (src_h < crop_min_h)
318 return -eMPPExeedSrcHCropMin;
319 else if (dest_h < dest_min_h)
320 return -eMPPExeedMinDstHeight;
321
322 return 1;
323 }
324
325 bool need_gsc_op_twice = false;
326 if (getDrmMode(handle->flags) != NO_DRM) {
327 need_gsc_op_twice = ((dest_w > src_w * max_upscale) ||
328 (dest_h > src_h * max_upscale)) ? true : false;
329 if (need_gsc_op_twice)
330 max_upscale = 8 * 8;
331 } else {
332 if (!mDisplay->mHasDrmSurface) {
333 need_gsc_op_twice = false;
334 max_upscale = 8;
335 }
336 }
337
338 if (getDrmMode(handle->flags) != NO_DRM) {
339 /* make even for gscaler */
340 layer.sourceCropf.top = (unsigned int)layer.sourceCropf.top & ~1;
341 layer.sourceCropf.left = (unsigned int)layer.sourceCropf.left & ~1;
342 layer.sourceCropf.bottom = (unsigned int)layer.sourceCropf.bottom & ~1;
343 layer.sourceCropf.right = (unsigned int)layer.sourceCropf.right & ~1;
344 }
345
346 /* check whether GSC can handle with M2M */
347 if (!isFormatSupportedByGsc(format))
348 return -eMPPUnsupportedFormat;
349 else if (src_w < min_w)
350 return -eMPPExeedMinSrcWidth;
351 else if (src_h < min_h)
352 return -eMPPExeedMinSrcHeight;
353 else if (!isDstCropWidthAligned(dest_w))
354 return -eMPPNotAlignedDstSize;
355 else if (handle->stride > max_w)
356 return -eMPPExceedHStrideMaximum;
357 else if (handle->stride % srcWidthAlign != 0)
358 return -eMPPNotAlignedHStride;
359 else if (src_w * downNumerator >= dest_w * downDenominator)
360 return -eMPPExeedMaxDownScale;
361 else if (dest_w > src_w * max_upscale)
362 return -eMPPExeedMaxUpScale;
363 else if (handle->vstride > max_h)
364 return -eMPPExceedVStrideMaximum;
365 else if (handle->vstride % srcHeightAlign != 0)
366 return -eMPPNotAlignedVStride;
367 else if (src_h * downNumerator >= dest_h * downDenominator)
368 return -eMPPExeedMaxDownScale;
369 else if (dest_h > src_h * max_upscale)
370 return -eMPPExeedMaxUpScale;
371 else if (src_w > crop_max_w)
372 return -eMPPExeedSrcWCropMax;
373 else if (src_h > crop_max_h)
374 return -eMPPExeedSrcHCropMax;
375 else if (src_w < crop_min_w)
376 return -eMPPExeedSrcWCropMin;
377 else if (src_h < crop_min_h)
378 return -eMPPExeedSrcHCropMin;
379 else if (dest_h < dest_min_h)
380 return -eMPPExeedMinDstHeight;
381 // per 46.3.1.6
382
383 return 1;
384 }
385
386 bool ExynosMPP::isProcessingRequired(hwc_layer_1_t &layer, int format)
387 {
388 return formatRequiresGsc(format) || isScaled(layer)
389 || isTransformed(layer);
390 }
391
392 int ExynosMPP::getAdjustedCrop(int rawSrcSize, int dstSize, int format, bool isVertical __unused, bool isRotated)
393 {
394 int ratio;
395 int align;
396
397 if (dstSize >= rawSrcSize || rawSrcSize <= dstSize * FIRST_PRESCALER_THRESHOLD)
398 ratio = 1;
399 else if (rawSrcSize < dstSize * SECOND_PRESCALER_THRESHOLD)
400 ratio = 2;
401 else
402 ratio = 4;
403
404 if (isFormatRgb(format)) {
405 if (isRotated)
406 align = ratio << 1;
407 else
408 align = ratio;
409 } else {
410 align = ratio << 1;
411 }
412
413 return rawSrcSize - (rawSrcSize % align);
414 }
415
416 void ExynosMPP::setupSource(exynos_mpp_img &src_img, hwc_layer_1_t &layer)
417 {
418 bool rotation = !!(layer.transform & HAL_TRANSFORM_ROT_90);
419 private_handle_t *src_handle = private_handle_t::dynamicCast(layer.handle);
420 src_img.x = ALIGN((unsigned int)layer.sourceCropf.left, srcXOffsetAlign(layer));
421 src_img.y = ALIGN((unsigned int)layer.sourceCropf.top, srcYOffsetAlign(layer));
422 src_img.w = WIDTH(layer.sourceCropf) - (src_img.x - (uint32_t)layer.sourceCropf.left);
423 src_img.fw = src_handle->stride;
424 if (src_img.x + src_img.w > src_img.fw)
425 src_img.w = src_img.fw - src_img.x;
426 src_img.h = HEIGHT(layer.sourceCropf) - (src_img.y - (uint32_t)layer.sourceCropf.top);
427 src_img.fh = src_handle->vstride;
428 if (src_img.y + src_img.h > src_img.fh)
429 src_img.h = src_img.fh - src_img.y;
430 src_img.yaddr = src_handle->fd;
431 if (!isUsingMSC()) {
432 src_img.w = getAdjustedCrop(src_img.w, WIDTH(layer.displayFrame), src_handle->format, false, rotation);
433 src_img.h = getAdjustedCrop(src_img.h, HEIGHT(layer.displayFrame), src_handle->format, true, rotation);
434 }
435 if (mS3DMode == S3D_SBS)
436 src_img.w /= 2;
437 if (mS3DMode == S3D_TB)
438 src_img.h /= 2;
439 if (isFormatYCrCb(src_handle->format)) {
440 src_img.uaddr = src_handle->fd2;
441 src_img.vaddr = src_handle->fd1;
442 } else {
443 src_img.uaddr = src_handle->fd1;
444 src_img.vaddr = src_handle->fd2;
445 }
446 if (src_handle->format != HAL_PIXEL_FORMAT_EXYNOS_YCrCb_420_SP_M_FULL)
447 src_img.format = src_handle->format;
448 else
449 src_img.format = HAL_PIXEL_FORMAT_EXYNOS_YCrCb_420_SP_M;
450
451 if (layer.blending == HWC_BLENDING_COVERAGE)
452 src_img.pre_multi = false;
453 else
454 src_img.pre_multi = true;
455
456 src_img.drmMode = !!(getDrmMode(src_handle->flags) == SECURE_DRM);
457 src_img.acquireFenceFd = layer.acquireFenceFd;
458 }
459
460 void ExynosMPP::setupOtfDestination(exynos_mpp_img &src_img, exynos_mpp_img &dst_img, hwc_layer_1_t &layer)
461 {
462 dst_img.x = layer.displayFrame.left;
463 dst_img.y = layer.displayFrame.top;
464 dst_img.fw = mDisplay->mXres;
465 dst_img.fh = mDisplay->mYres;
466 dst_img.w = WIDTH(layer.displayFrame);
467 dst_img.h = HEIGHT(layer.displayFrame);
468 dst_img.w = min(dst_img.w, dst_img.fw - dst_img.x);
469 dst_img.h = min(dst_img.h, dst_img.fh - dst_img.y);
470 dst_img.format = HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SP_M;
471 dst_img.rot = layer.transform;
472 dst_img.drmMode = src_img.drmMode;
473 dst_img.yaddr = (ptrdiff_t)NULL;
474 }
475
476 int ExynosMPP::sourceWidthAlign(int format __unused)
477 {
478 return 16;
479 }
480
481 int ExynosMPP::sourceHeightAlign(int format __unused)
482 {
483 return 16;
484 }
485
486 int ExynosMPP::destinationAlign(int format __unused)
487 {
488 return 16;
489 }
490
491 int ExynosMPP::reconfigureOtf(exynos_mpp_img *src_img, exynos_mpp_img *dst_img)
492 {
493 int ret = 0;
494 if (mGscHandle) {
495 ret = stopMPP(mGscHandle);
496 if (ret < 0) {
497 ALOGE("failed to stop gscaler %u", mIndex);
498 return ret;
499 }
500 mNeedReqbufs = true;
501 mCountSameConfig = 0;
502 }
503
504 if (!mGscHandle) {
505 mGscHandle = createMPP(AVAILABLE_GSC_UNITS[mIndex],
506 GSC_OUTPUT_MODE, GSC_OUT_FIMD, false);
507 if (!mGscHandle) {
508 ALOGE("failed to create gscaler handle");
509 return -1;
510 }
511 }
512
513 ret = configMPP(mGscHandle, src_img, dst_img);
514 if (ret < 0) {
515 ALOGE("failed to configure gscaler %u", mIndex);
516 return ret;
517 }
518
519 return ret;
520 }
521
522 int ExynosMPP::processOTF(hwc_layer_1_t &layer)
523 {
524 ATRACE_CALL();
525 ALOGV("configuring gscaler %u for memory-to-fimd-localout", mIndex);
526
527 int ret = 0;
528
529 int dstAlign;
530
531 exynos_mpp_img src_img, dst_img;
532 memset(&src_img, 0, sizeof(src_img));
533 memset(&dst_img, 0, sizeof(dst_img));
534
535 setupSource(src_img, layer);
536 setupOtfDestination(src_img, dst_img, layer);
537
538 dstAlign = destinationAlign(dst_img.format);
539
540 ALOGV("source configuration:");
541 dumpMPPImage(src_img);
542
543 if (!mGscHandle || isSrcConfigChanged(src_img, mSrcConfig) ||
544 isDstConfigChanged(dst_img, mDstConfig)) {
545 if (!isPerFrameSrcChanged(src_img, mSrcConfig) ||
546 !isPerFrameDstChanged(dst_img, mDstConfig)) {
547 ret = reconfigureOtf(&src_img, &dst_img);
548 if (ret < 0)
549 goto err_gsc_local;
550 }
551 }
552
553 if (isSourceCropChanged(src_img, mSrcConfig)) {
554 setInputCrop(mGscHandle, &src_img, &dst_img);
555 }
556
557 ALOGV("destination configuration:");
558 dumpMPPImage(dst_img);
559
560 ret = runMPP(mGscHandle, &src_img, &dst_img);
561 if (ret < 0) {
562 ALOGE("failed to run gscaler %u", mIndex);
563 goto err_gsc_local;
564 }
565
566 memcpy(&mSrcConfig, &src_img, sizeof(mSrcConfig));
567 memcpy(&mDstConfig, &dst_img, sizeof(mDstConfig));
568
569 return 0;
570
571 err_gsc_local:
572 if (src_img.acquireFenceFd >= 0)
573 close(src_img.acquireFenceFd);
574
575 memset(&mSrcConfig, 0, sizeof(mSrcConfig));
576 memset(&mDstConfig, 0, sizeof(mDstConfig));
577
578 return ret;
579 }
580
581 bool ExynosMPP::setupDoubleOperation(exynos_mpp_img &src_img, exynos_mpp_img &mid_img, hwc_layer_1_t &layer)
582 {
583 /* check if GSC need to operate twice */
584 bool need_gsc_op_twice = false;
585 bool need_unscaled_csc = false;
586 private_handle_t *src_handle = private_handle_t::dynamicCast(layer.handle);
587 const int max_upscale = 8;
588 bool rot90or270 = !!(layer.transform & HAL_TRANSFORM_ROT_90);
589 int src_w = WIDTH(layer.sourceCropf), src_h = HEIGHT(layer.sourceCropf);
590 int dest_w, dest_h;
591 if (rot90or270) {
592 dest_w = HEIGHT(layer.displayFrame);
593 dest_h = WIDTH(layer.displayFrame);
594 } else {
595 dest_w = WIDTH(layer.displayFrame);
596 dest_h = HEIGHT(layer.displayFrame);
597 }
598 if (getDrmMode(src_handle->flags) != NO_DRM)
599 need_gsc_op_twice = ((dest_w > src_w * max_upscale) ||
600 (dest_h > src_h * max_upscale)) ? true : false;
601
602 if (isUsingMSC() && src_handle->format == HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SP_M_TILED) {
603 need_gsc_op_twice = true;
604 need_unscaled_csc = true;
605 }
606
607 if (need_gsc_op_twice) {
608 mid_img.x = 0;
609 mid_img.y = 0;
610
611 int mid_w = 0, mid_h = 0;
612
613 if (need_unscaled_csc) {
614 mid_img.w = src_w;
615 mid_img.h = src_h;
616 } else {
617 if (rot90or270) {
618 mid_w = HEIGHT(layer.displayFrame);
619 mid_h = WIDTH(layer.displayFrame);
620 } else {
621 mid_w = WIDTH(layer.displayFrame);
622 mid_h = HEIGHT(layer.displayFrame);
623 }
624
625 if (WIDTH(layer.sourceCropf) * max_upscale < mid_w)
626 mid_img.w = (((mid_w + 7) / 8) + 1) & ~1;
627 else
628 mid_img.w = mid_w;
629
630 if (HEIGHT(layer.sourceCropf) * max_upscale < mid_h)
631 mid_img.h = (((mid_h + 7) / 8) + 1) & ~1;
632 else
633 mid_img.h = mid_h;
634 }
635 mid_img.drmMode = src_img.drmMode;
636 mid_img.format = HAL_PIXEL_FORMAT_EXYNOS_YCrCb_420_SP_M;
637
638 if (layer.blending == HWC_BLENDING_PREMULT || layer.blending == HWC_BLENDING_COVERAGE)
639 mid_img.pre_multi = false;
640 else
641 mid_img.pre_multi = true;
642
643 mid_img.mem_type = GSC_MEM_DMABUF;
644 mid_img.narrowRgb = !isFormatRgb(src_handle->format);
645 }
646
647 return need_gsc_op_twice;
648 }
649
650 void ExynosMPP::setupM2MDestination(exynos_mpp_img &src_img, exynos_mpp_img &dst_img,
651 int dst_format, hwc_layer_1_t &layer, hwc_frect_t *sourceCrop)
652 {
653 private_handle_t *src_handle = private_handle_t::dynamicCast(layer.handle);
654 dst_img.x = 0;
655 dst_img.y = 0;
656 dst_img.w = WIDTH(layer.displayFrame);
657 dst_img.h = HEIGHT(layer.displayFrame);
658 dst_img.rot = layer.transform;
659 dst_img.drmMode = src_img.drmMode;
660 dst_img.format = dst_format;
661
662 if (layer.blending == HWC_BLENDING_PREMULT || layer.blending == HWC_BLENDING_COVERAGE)
663 dst_img.pre_multi = false;
664 else
665 dst_img.pre_multi = true;
666
667 dst_img.mem_type = GSC_MEM_DMABUF;
668 if (src_handle->format == HAL_PIXEL_FORMAT_EXYNOS_YCrCb_420_SP_M_FULL)
669 dst_img.narrowRgb = 0;
670 else
671 dst_img.narrowRgb = !isFormatRgb(src_handle->format);
672 if (dst_img.drmMode)
673 alignCropAndCenter(dst_img.w, dst_img.h, sourceCrop,
674 GSC_DST_CROP_W_ALIGNMENT_RGB888);
675 }
676
677 int ExynosMPP::reallocateBuffers(private_handle_t *src_handle, exynos_mpp_img &dst_img, exynos_mpp_img &mid_img, bool need_gsc_op_twice)
678 {
679 ATRACE_CALL();
680 alloc_device_t* alloc_device = mDisplay->mAllocDevice;
681 int ret = 0;
682 int dst_stride;
683 int usage = GRALLOC_USAGE_SW_READ_NEVER |
684 GRALLOC_USAGE_SW_WRITE_NEVER |
685 GRALLOC_USAGE_NOZEROED |
686 #ifdef USE_FB_PHY_LINEAR
687 ((mIndex == FIMD_GSC_IDX) ? GRALLOC_USAGE_PHYSICALLY_LINEAR : 0) |
688 #endif
689 GRALLOC_USAGE_HW_COMPOSER;
690
691 #ifdef USE_FB_PHY_LINEAR
692 usage |= GRALLOC_USAGE_PROTECTED;
693 usage &= ~GRALLOC_USAGE_PRIVATE_NONSECURE;
694 #else
695 if (getDrmMode(src_handle->flags) == SECURE_DRM) {
696 usage |= GRALLOC_USAGE_PROTECTED;
697 usage &= ~GRALLOC_USAGE_PRIVATE_NONSECURE;
698 } else if (getDrmMode(src_handle->flags) == NORMAL_DRM) {
699 usage |= GRALLOC_USAGE_PROTECTED;
700 usage |= GRALLOC_USAGE_PRIVATE_NONSECURE;
701 }
702 #endif
703 /* HACK: for distinguishing FIMD_VIDEO region */
704 if (!(src_handle->format == HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_PN ||
705 src_handle->format == HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SPN ||
706 src_handle->format == HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SPN_TILED)) {
707 usage |= (GRALLOC_USAGE_HW_TEXTURE | GRALLOC_USAGE_HW_RENDER);
708 }
709
710 int w, h;
711 {
712 int dstAlign = destinationAlign(dst_img.format);
713 w = ALIGN(mDisplay->mXres, dstAlign);
714 h = ALIGN(mDisplay->mYres, dstAlign);
715 }
716
717 for (size_t i = 0; i < NUM_GSC_DST_BUFS; i++) {
718 if (mDstBuffers[i]) {
719 android::Mutex::Autolock lock(mMutex);
720 mFreedBuffers.push_back(mDstBuffers[i]);
721 mDstBuffers[i] = NULL;
722 }
723
724 if (mDstBufFence[i] >= 0) {
725 close(mDstBufFence[i]);
726 mDstBufFence[i] = -1;
727 }
728
729 if (mMidBuffers[i] != NULL) {
730 android::Mutex::Autolock lock(mMutex);
731 mFreedBuffers.push_back(mMidBuffers[i]);
732 mMidBuffers[i] = NULL;
733 }
734
735 if (mMidBufFence[i] >= 0) {
736 close(mMidBufFence[i]);
737 mMidBufFence[i] = -1;
738 }
739 }
740
741 if (getDrmMode(src_handle->flags) != NO_DRM &&
742 mDisplay != NULL && mDisplay->mHwc != NULL &&
743 (ExynosDisplay *)mDisplay->mHwc->externalDisplay == mDisplay)
744 mNumAvailableDstBuffers = NUM_DRM_GSC_DST_BUFS;
745 else
746 mNumAvailableDstBuffers = NUM_GSC_DST_BUFS;
747
748 for (size_t i = 0; i < mNumAvailableDstBuffers; i++) {
749 int format = dst_img.format;
750 ret = alloc_device->alloc(alloc_device, w, h,
751 format, usage, &mDstBuffers[i],
752 &dst_stride);
753 if (ret < 0) {
754 ALOGE("failed to allocate destination buffer(%dx%d): %s", w, h,
755 strerror(-ret));
756 return ret;
757 }
758
759 if (need_gsc_op_twice) {
760 ret = alloc_device->alloc(alloc_device, mid_img.w, mid_img.h,
761 HAL_PIXEL_FORMAT_EXYNOS_YCrCb_420_SP_M, usage, &mMidBuffers[i],
762 &dst_stride);
763 if (ret < 0) {
764 ALOGE("failed to allocate intermediate buffer(%dx%d): %s", mid_img.w, mid_img.h,
765 strerror(-ret));
766 return ret;
767 }
768 }
769 }
770 {
771 android::Mutex::Autolock lock(mMutex);
772 mBufferFreeThread->mCondition.signal();
773 }
774 return ret;
775 }
776
777 #ifdef USES_VIRTUAL_DISPLAY
778 int ExynosMPP::processM2M(hwc_layer_1_t &layer, int dst_format, hwc_frect_t *sourceCrop, bool isNeedBufferAlloc)
779 #else
780 int ExynosMPP::processM2M(hwc_layer_1_t &layer, int dst_format, hwc_frect_t *sourceCrop)
781 #endif
782 {
783 ATRACE_CALL();
784 ALOGV("configuring gscaler %u for memory-to-memory", AVAILABLE_GSC_UNITS[mIndex]);
785
786 #ifdef USES_VIRTUAL_DISPLAY
787 alloc_device_t* alloc_device = mDisplay->mAllocDevice;
788 #endif
789 private_handle_t *src_handle = private_handle_t::dynamicCast(layer.handle);
790 buffer_handle_t dst_buf;
791 private_handle_t *dst_handle;
792 buffer_handle_t mid_buf;
793 private_handle_t *mid_handle;
794 int ret = 0;
795
796 if (isUsingMSC()) {
797 if (dst_format != HAL_PIXEL_FORMAT_RGB_565)
798 dst_format = HAL_PIXEL_FORMAT_BGRA_8888;
799 }
800
801 exynos_mpp_img src_img, dst_img;
802 memset(&src_img, 0, sizeof(src_img));
803 memset(&dst_img, 0, sizeof(dst_img));
804 exynos_mpp_img mid_img;
805 memset(&mid_img, 0, sizeof(mid_img));
806
807 hwc_frect_t sourceCropTemp;
808 if (!sourceCrop)
809 sourceCrop = &sourceCropTemp;
810
811 setupSource(src_img, layer);
812 src_img.mem_type = GSC_MEM_DMABUF;
813
814 if (isUsingMSC()) {
815 if (src_img.format == HAL_PIXEL_FORMAT_RGBA_8888 || src_img.format == HAL_PIXEL_FORMAT_RGBX_8888)
816 src_img.format = HAL_PIXEL_FORMAT_BGRA_8888;
817 }
818
819 bool need_gsc_op_twice = setupDoubleOperation(src_img, mid_img, layer);
820
821 setupM2MDestination(src_img, dst_img, dst_format, layer, sourceCrop);
822
823 #ifdef USES_VIRTUAL_DISPLAY
824 if (!isNeedBufferAlloc) {
825 dst_img.x = mDisplay->mHwc->mVirtualDisplayRect.left;
826 dst_img.y = mDisplay->mHwc->mVirtualDisplayRect.top;
827 dst_img.w = mDisplay->mHwc->mVirtualDisplayRect.width;
828 dst_img.h = mDisplay->mHwc->mVirtualDisplayRect.height;
829 }
830 #endif
831
832 ALOGV("source configuration:");
833 dumpMPPImage(src_img);
834
835 bool reconfigure = isSrcConfigChanged(src_img, mSrcConfig) ||
836 isDstConfigChanged(dst_img, mDstConfig);
837
838 #ifdef USES_VIRTUAL_DISPLAY
839 if (isNeedBufferAlloc) {
840 #endif
841 bool realloc = mDstConfig.fw <= 0 || formatToBpp(mDstConfig.format) != formatToBpp(dst_format);
842
843 /* ext_only andn int_only changes */
844 if (!need_gsc_op_twice && getDrmMode(src_handle->flags) == SECURE_DRM) {
845 if (dst_img.drmMode != mDstConfig.drmMode)
846 realloc = true;
847 else
848 realloc = false;
849 }
850
851 if (need_gsc_op_twice && isSrcConfigChanged(mid_img, mMidConfig))
852 realloc = true;
853
854 if (need_gsc_op_twice && !mDoubleOperation)
855 realloc = true;
856 mDoubleOperation = need_gsc_op_twice;
857
858 if (reconfigure && realloc) {
859 if ((ret = reallocateBuffers(src_handle, dst_img, mid_img, need_gsc_op_twice)) < 0)
860 goto err_alloc;
861
862 mCurrentBuf = 0;
863 mLastGSCLayerHandle = 0;
864 }
865
866 if (!reconfigure && (mLastGSCLayerHandle == (ptrdiff_t)layer.handle)) {
867 ALOGV("[USE] GSC_SKIP_DUPLICATE_FRAME_PROCESSING\n");
868 if (layer.acquireFenceFd >= 0)
869 close(layer.acquireFenceFd);
870
871 layer.releaseFenceFd = -1;
872 layer.acquireFenceFd = -1;
873 mDstConfig.releaseFenceFd = -1;
874
875 mCurrentBuf = (mCurrentBuf + mNumAvailableDstBuffers- 1) % mNumAvailableDstBuffers;
876 return 0;
877 } else {
878 mLastGSCLayerHandle = (ptrdiff_t)layer.handle;
879 }
880 #ifdef USES_VIRTUAL_DISPLAY
881 } else {
882 if (reconfigure && need_gsc_op_twice) {
883 int dst_stride;
884 if (mMidBuffers[0] != NULL) {
885 android::Mutex::Autolock lock(mMutex);
886 mFreedBuffers.push_back(mMidBuffers[0]);
887 mBufferFreeThread->mCondition.signal();
888 mMidBuffers[0] = NULL;
889 }
890
891 if (mMidBufFence[0] >= 0) {
892 close(mMidBufFence[0]);
893 mMidBufFence[0] = -1;
894 }
895
896 ret = alloc_device->alloc(alloc_device, mid_img.w, mid_img.h,
897 HAL_PIXEL_FORMAT_EXYNOS_YCrCb_420_SP_M, ((ExynosVirtualDisplay*)mDisplay)->mSinkUsage, &mMidBuffers[0],
898 &dst_stride);
899 if (ret < 0) {
900 ALOGE("failed to allocate intermediate buffer(%dx%d): %s", mid_img.w, mid_img.h,
901 strerror(-ret));
902 goto err_alloc;
903 }
904 }
905 }
906 #endif
907
908 layer.acquireFenceFd = -1;
909 if (need_gsc_op_twice) {
910 mid_img.acquireFenceFd = mMidBufFence[mCurrentBuf];
911 mMidBufFence[mCurrentBuf] = -1;
912 mid_buf = mMidBuffers[mCurrentBuf];
913 mid_handle = private_handle_t::dynamicCast(mid_buf);
914
915 mid_img.fw = mid_handle->stride;
916 mid_img.fh = mid_handle->vstride;
917 mid_img.yaddr = mid_handle->fd;
918 if (isFormatYCrCb(mid_handle->format)) {
919 mid_img.uaddr = mid_handle->fd2;
920 mid_img.vaddr = mid_handle->fd1;
921 } else {
922 mid_img.uaddr = mid_handle->fd1;
923 mid_img.vaddr = mid_handle->fd2;
924 }
925 //mid_img.acquireFenceFd = -1;
926
927 ALOGV("mid configuration:");
928 dumpMPPImage(mid_img);
929 }
930
931 dst_buf = mDstBuffers[mCurrentBuf];
932 dst_handle = private_handle_t::dynamicCast(dst_buf);
933
934 dst_img.fw = dst_handle->stride;
935 dst_img.fh = dst_handle->vstride;
936 dst_img.yaddr = dst_handle->fd;
937 dst_img.uaddr = dst_handle->fd1;
938 dst_img.vaddr = dst_handle->fd2;
939 dst_img.acquireFenceFd = mDstBufFence[mCurrentBuf];
940 mDstBufFence[mCurrentBuf] = -1;
941
942 ALOGV("destination configuration:");
943 dumpMPPImage(dst_img);
944
945 if ((int)dst_img.w != WIDTH(layer.displayFrame))
946 ALOGV("padding %u x %u output to %u x %u and cropping to {%7.1f,%7.1f,%7.1f,%7.1f}",
947 WIDTH(layer.displayFrame), HEIGHT(layer.displayFrame),
948 dst_img.w, dst_img.h, sourceCrop->left, sourceCrop->top,
949 sourceCrop->right, sourceCrop->bottom);
950
951 if (mGscHandle) {
952 ALOGV("reusing open gscaler %u", AVAILABLE_GSC_UNITS[mIndex]);
953 } else {
954 ALOGV("opening gscaler %u", AVAILABLE_GSC_UNITS[mIndex]);
955 mGscHandle = createMPP(
956 AVAILABLE_GSC_UNITS[mIndex], GSC_M2M_MODE, GSC_DUMMY, (getDrmMode(src_handle->flags) != NO_DRM));
957 if (!mGscHandle) {
958 ALOGE("failed to create gscaler handle");
959 ret = -1;
960 goto err_alloc;
961 }
962 }
963
964 if (!need_gsc_op_twice)
965 memcpy(&mid_img, &dst_img, sizeof(exynos_mpp_img));
966
967 /* src -> mid or src->dest */
968 if (reconfigure || need_gsc_op_twice) {
969 ret = stopMPP(mGscHandle);
970 if (ret < 0) {
971 ALOGE("failed to stop gscaler %u", mIndex);
972 goto err_gsc_config;
973 }
974
975 ret = setCSCProperty(mGscHandle, 0, !mid_img.narrowRgb, 1);
976 ret = configMPP(mGscHandle, &src_img, &mid_img);
977 if (ret < 0) {
978 ALOGE("failed to configure gscaler %u", mIndex);
979 goto err_gsc_config;
980 }
981 }
982
983 ret = runMPP(mGscHandle, &src_img, &mid_img);
984 if (ret < 0) {
985 ALOGE("failed to run gscaler %u", mIndex);
986 goto err_gsc_config;
987 }
988
989 /* mid -> dst */
990 if (need_gsc_op_twice) {
991 ret = stopMPP(mGscHandle);
992 if (ret < 0) {
993 ALOGE("failed to stop gscaler %u", mIndex);
994 goto err_gsc_config;
995 }
996
997 mid_img.acquireFenceFd = mid_img.releaseFenceFd;
998
999 ret = setCSCProperty(mGscHandle, 0, !dst_img.narrowRgb, 1);
1000 ret = configMPP(mGscHandle, &mid_img, &dst_img);
1001 if (ret < 0) {
1002 ALOGE("failed to configure gscaler %u", mIndex);
1003 goto err_gsc_config;
1004 }
1005
1006 ret = runMPP(mGscHandle, &mid_img, &dst_img);
1007 if (ret < 0) {
1008 ALOGE("failed to run gscaler %u", mIndex);
1009 goto err_gsc_config;
1010 }
1011 mMidBufFence[mCurrentBuf] = mid_img.releaseFenceFd;
1012 }
1013
1014 mSrcConfig = src_img;
1015 mMidConfig = mid_img;
1016
1017 if (need_gsc_op_twice) {
1018 mDstConfig = dst_img;
1019 } else {
1020 mDstConfig = mid_img;
1021 }
1022
1023 layer.releaseFenceFd = src_img.releaseFenceFd;
1024
1025 return 0;
1026
1027 err_gsc_config:
1028 if (mGscHandle)
1029 destroyMPP(mGscHandle);
1030 mGscHandle = NULL;
1031 libmpp = NULL;
1032 err_alloc:
1033 if (src_img.acquireFenceFd >= 0)
1034 close(src_img.acquireFenceFd);
1035 #ifdef USES_VIRTUAL_DISPLAY
1036 if (isNeedBufferAlloc) {
1037 #endif
1038 for (size_t i = 0; i < NUM_GSC_DST_BUFS; i++) {
1039 if (mDstBuffers[i]) {
1040 android::Mutex::Autolock lock(mMutex);
1041 mFreedBuffers.push_back(mDstBuffers[i]);
1042 mDstBuffers[i] = NULL;
1043 }
1044 if (mDstBufFence[i] >= 0) {
1045 close(mDstBufFence[i]);
1046 mDstBufFence[i] = -1;
1047 }
1048 if (mMidBuffers[i]) {
1049 android::Mutex::Autolock lock(mMutex);
1050 mFreedBuffers.push_back(mMidBuffers[i]);
1051 mMidBuffers[i] = NULL;
1052 }
1053 if (mMidBufFence[i] >= 0) {
1054 close(mMidBufFence[i]);
1055 mMidBufFence[i] = -1;
1056 }
1057 }
1058 #ifdef USES_VIRTUAL_DISPLAY
1059 } else {
1060 if (mMidBuffers[0]) {
1061 android::Mutex::Autolock lock(mMutex);
1062 mFreedBuffers.push_back(mMidBuffers[0]);
1063 mMidBuffers[0] = NULL;
1064 }
1065 if (mMidBufFence[0] >= 0) {
1066 close(mMidBufFence[0]);
1067 mMidBufFence[0] = -1;
1068 }
1069 }
1070 #endif
1071 {
1072 android::Mutex::Autolock lock(mMutex);
1073 mBufferFreeThread->mCondition.signal();
1074 }
1075 memset(&mSrcConfig, 0, sizeof(mSrcConfig));
1076 memset(&mDstConfig, 0, sizeof(mDstConfig));
1077 memset(&mMidConfig, 0, sizeof(mMidConfig));
1078 return ret;
1079 }
1080
1081 void ExynosMPP::cleanupM2M()
1082 {
1083 cleanupM2M(false);
1084 }
1085
1086 void ExynosMPP::cleanupM2M(bool noFenceWait)
1087 {
1088 ATRACE_CALL();
1089 if (!mGscHandle)
1090 return;
1091
1092 ALOGV("closing gscaler %u", AVAILABLE_GSC_UNITS[mIndex]);
1093
1094 if (!noFenceWait) {
1095 for (size_t i = 0; i < NUM_GSC_DST_BUFS; i++) {
1096 #ifndef FORCEFB_YUVLAYER
1097 if (mDstBufFence[i] >= 0)
1098 if (sync_wait(mDstBufFence[i], 1000) < 0)
1099 ALOGE("sync_wait error");
1100 #endif
1101 if (mMidBufFence[i] >= 0)
1102 if (sync_wait(mMidBufFence[i], 1000) < 0)
1103 ALOGE("sync_wait error");
1104 }
1105 }
1106
1107 if (mGscHandle) {
1108 stopMPP(mGscHandle);
1109 destroyMPP(mGscHandle);
1110 }
1111 for (size_t i = 0; i < NUM_GSC_DST_BUFS; i++) {
1112 if (mDstBuffers[i]) {
1113 android::Mutex::Autolock lock(mMutex);
1114 mFreedBuffers.push_back(mDstBuffers[i]);
1115 }
1116 if (mDstBufFence[i] >= 0)
1117 close(mDstBufFence[i]);
1118 if (mMidBuffers[i]) {
1119 android::Mutex::Autolock lock(mMutex);
1120 mFreedBuffers.push_back(mMidBuffers[i]);
1121 mMidBuffers[i] = NULL;
1122 }
1123 if (mMidBufFence[i] >= 0)
1124 close(mMidBufFence[i]);
1125 }
1126 {
1127 android::Mutex::Autolock lock(mMutex);
1128 mBufferFreeThread->mCondition.signal();
1129 }
1130
1131 mGscHandle = NULL;
1132 libmpp = NULL;
1133 memset(&mSrcConfig, 0, sizeof(mSrcConfig));
1134 memset(&mMidConfig, 0, sizeof(mMidConfig));
1135 memset(&mDstConfig, 0, sizeof(mDstConfig));
1136 memset(mDstBuffers, 0, sizeof(mDstBuffers));
1137 memset(mMidBuffers, 0, sizeof(mMidBuffers));
1138 mCurrentBuf = 0;
1139 mGSCMode = 0;
1140 mLastGSCLayerHandle = 0;
1141
1142 for (size_t i = 0; i < NUM_GSC_DST_BUFS; i++) {
1143 mDstBufFence[i] = -1;
1144 mMidBufFence[i] = -1;
1145 }
1146 }
1147
1148 void ExynosMPP::cleanupOTF()
1149 {
1150 if (mGscHandle) {
1151 stopMPP(mGscHandle);
1152 freeMPP(mGscHandle);
1153 }
1154
1155 mNeedReqbufs = false;
1156 mWaitVsyncCount = 0;
1157 mDisplay->mOtfMode = OTF_OFF;
1158 mGscHandle = NULL;
1159 libmpp = NULL;
1160 memset(&mSrcConfig, 0, sizeof(mSrcConfig));
1161 memset(&mMidConfig, 0, sizeof(mMidConfig));
1162 memset(&mDstConfig, 0, sizeof(mDstConfig));
1163 memset(mDstBuffers, 0, sizeof(mDstBuffers));
1164 memset(mMidBuffers, 0, sizeof(mMidBuffers));
1165 mCurrentBuf = 0;
1166 mGSCMode = 0;
1167 mLastGSCLayerHandle = 0;
1168
1169 for (size_t i = 0; i < NUM_GSC_DST_BUFS; i++) {
1170 mDstBufFence[i] = -1;
1171 mMidBufFence[i] = -1;
1172 }
1173 }
1174
1175 bool ExynosMPP::rotationSupported(bool rotation)
1176 {
1177 return !rotation;
1178 }
1179
1180 bool ExynosMPP::paritySupported(int w, int h)
1181 {
1182 return (w % 2 == 0) && (h % 2 == 0);
1183 }
1184
1185 bool ExynosMPP::isDstConfigChanged(exynos_mpp_img &c1, exynos_mpp_img &c2)
1186 {
1187 return c1.x != c2.x ||
1188 c1.y != c2.y ||
1189 c1.w != c2.w ||
1190 c1.h != c2.h ||
1191 c1.format != c2.format ||
1192 c1.rot != c2.rot ||
1193 c1.narrowRgb != c2.narrowRgb ||
1194 c1.cacheable != c2.cacheable ||
1195 c1.pre_multi != c2.pre_multi ||
1196 c1.drmMode != c2.drmMode;
1197 }
1198
1199 bool ExynosMPP::isSourceCropChanged(exynos_mpp_img &c1 __unused, exynos_mpp_img &c2 __unused)
1200 {
1201 return false;
1202 }
1203
1204 bool ExynosMPP::isPerFrameSrcChanged(exynos_mpp_img &c1 __unused, exynos_mpp_img &c2 __unused)
1205 {
1206 return false;
1207 }
1208
1209 bool ExynosMPP::isPerFrameDstChanged(exynos_mpp_img &c1 __unused, exynos_mpp_img &c2 __unused)
1210 {
1211 return false;
1212 }
1213
1214 bool ExynosMPP::isReallocationRequired(int w, int h, exynos_mpp_img &c1, exynos_mpp_img &c2)
1215 {
1216 return ALIGN(w, GSC_W_ALIGNMENT) != ALIGN(c2.fw, GSC_W_ALIGNMENT) ||
1217 ALIGN(h, GSC_H_ALIGNMENT) != ALIGN(c2.fh, GSC_H_ALIGNMENT) ||
1218 c1.format != c2.format ||
1219 c1.drmMode != c2.drmMode;
1220 }
1221
1222 uint32_t ExynosMPP::halFormatToMPPFormat(int format)
1223 {
1224 switch (format) {
1225 case HAL_PIXEL_FORMAT_RGBA_8888:
1226 return HAL_PIXEL_FORMAT_BGRA_8888;
1227 case HAL_PIXEL_FORMAT_BGRA_8888:
1228 return HAL_PIXEL_FORMAT_RGBA_8888;
1229 case HAL_PIXEL_FORMAT_EXYNOS_YCrCb_420_SP_M_FULL:
1230 return HAL_PIXEL_FORMAT_EXYNOS_YCrCb_420_SP_M;
1231 default:
1232 return format;
1233 }
1234 }
1235
1236 int ExynosMPP::minWidth(hwc_layer_1_t &layer)
1237 {
1238 private_handle_t *handle = private_handle_t::dynamicCast(layer.handle);
1239 switch (handle->format) {
1240 case HAL_PIXEL_FORMAT_RGBA_8888:
1241 case HAL_PIXEL_FORMAT_RGBX_8888:
1242 case HAL_PIXEL_FORMAT_RGB_565:
1243 return isRotated(layer) ? 16 : 32;
1244 case HAL_PIXEL_FORMAT_EXYNOS_YV12_M:
1245 case HAL_PIXEL_FORMAT_YV12:
1246 case HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_P_M:
1247 case HAL_PIXEL_FORMAT_EXYNOS_YCrCb_420_SP_M:
1248 case HAL_PIXEL_FORMAT_EXYNOS_YCrCb_420_SP_M_FULL:
1249 case HAL_PIXEL_FORMAT_YCrCb_420_SP:
1250 case HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SP_M:
1251 case HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SP_M_PRIV:
1252 case HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SP_M_TILED:
1253 default:
1254 return isRotated(layer) ? 32 : 64;
1255 }
1256 }
1257
1258 int ExynosMPP::minHeight(hwc_layer_1_t &layer)
1259 {
1260 private_handle_t *handle = private_handle_t::dynamicCast(layer.handle);
1261 switch (handle->format) {
1262 case HAL_PIXEL_FORMAT_RGBA_8888:
1263 case HAL_PIXEL_FORMAT_RGBX_8888:
1264 case HAL_PIXEL_FORMAT_RGB_565:
1265 return isRotated(layer) ? 32 : 16;
1266 case HAL_PIXEL_FORMAT_EXYNOS_YV12_M:
1267 case HAL_PIXEL_FORMAT_YV12:
1268 case HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_P_M:
1269 case HAL_PIXEL_FORMAT_EXYNOS_YCrCb_420_SP_M:
1270 case HAL_PIXEL_FORMAT_EXYNOS_YCrCb_420_SP_M_FULL:
1271 case HAL_PIXEL_FORMAT_YCrCb_420_SP:
1272 case HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SP_M:
1273 case HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SP_M_PRIV:
1274 case HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SP_M_TILED:
1275 default:
1276 return isRotated(layer) ? 64 : 32;
1277 }
1278 }
1279
1280 int ExynosMPP::maxWidth(hwc_layer_1_t &layer)
1281 {
1282 private_handle_t *handle = private_handle_t::dynamicCast(layer.handle);
1283
1284 if (isUsingMSC())
1285 return 8192;
1286
1287 switch (handle->format) {
1288 case HAL_PIXEL_FORMAT_RGBA_8888:
1289 case HAL_PIXEL_FORMAT_RGBX_8888:
1290 case HAL_PIXEL_FORMAT_RGB_565:
1291 case HAL_PIXEL_FORMAT_EXYNOS_YV12_M:
1292 case HAL_PIXEL_FORMAT_YV12:
1293 case HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_P_M:
1294 case HAL_PIXEL_FORMAT_EXYNOS_YCrCb_420_SP_M:
1295 case HAL_PIXEL_FORMAT_EXYNOS_YCrCb_420_SP_M_FULL:
1296 case HAL_PIXEL_FORMAT_YCrCb_420_SP:
1297 case HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SP_M:
1298 case HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SP_M_PRIV:
1299 return 4800;
1300 case HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SP_M_TILED:
1301 default:
1302 return 2047;
1303 }
1304 }
1305
1306 int ExynosMPP::maxHeight(hwc_layer_1_t &layer)
1307 {
1308 private_handle_t *handle = private_handle_t::dynamicCast(layer.handle);
1309
1310 if (isUsingMSC())
1311 return 8192;
1312
1313 switch (handle->format) {
1314 case HAL_PIXEL_FORMAT_RGBA_8888:
1315 case HAL_PIXEL_FORMAT_RGBX_8888:
1316 case HAL_PIXEL_FORMAT_RGB_565:
1317 case HAL_PIXEL_FORMAT_EXYNOS_YV12_M:
1318 case HAL_PIXEL_FORMAT_YV12:
1319 case HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_P_M:
1320 case HAL_PIXEL_FORMAT_EXYNOS_YCrCb_420_SP_M:
1321 case HAL_PIXEL_FORMAT_EXYNOS_YCrCb_420_SP_M_FULL:
1322 case HAL_PIXEL_FORMAT_YCrCb_420_SP:
1323 case HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SP_M:
1324 case HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SP_M_PRIV:
1325 return 3344;
1326 case HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SP_M_TILED:
1327 default:
1328 return 2047;
1329 }
1330 }
1331
1332 int ExynosMPP::srcXOffsetAlign(hwc_layer_1_t &layer)
1333 {
1334 private_handle_t *handle = private_handle_t::dynamicCast(layer.handle);
1335 switch (handle->format) {
1336 case HAL_PIXEL_FORMAT_RGBA_8888:
1337 case HAL_PIXEL_FORMAT_RGBX_8888:
1338 case HAL_PIXEL_FORMAT_RGB_565:
1339 return 1;
1340 case HAL_PIXEL_FORMAT_EXYNOS_YV12_M:
1341 case HAL_PIXEL_FORMAT_YV12:
1342 case HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_P_M:
1343 case HAL_PIXEL_FORMAT_EXYNOS_YCrCb_420_SP_M:
1344 case HAL_PIXEL_FORMAT_EXYNOS_YCrCb_420_SP_M_FULL:
1345 case HAL_PIXEL_FORMAT_YCrCb_420_SP:
1346 case HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SP_M:
1347 case HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SP_M_PRIV:
1348 case HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SP_M_TILED:
1349 default:
1350 return 2;
1351 }
1352 }
1353
1354 int ExynosMPP::srcYOffsetAlign(hwc_layer_1_t &layer)
1355 {
1356 private_handle_t *handle = private_handle_t::dynamicCast(layer.handle);
1357 switch (handle->format) {
1358 case HAL_PIXEL_FORMAT_RGBA_8888:
1359 case HAL_PIXEL_FORMAT_RGBX_8888:
1360 case HAL_PIXEL_FORMAT_RGB_565:
1361 case HAL_PIXEL_FORMAT_EXYNOS_YV12_M:
1362 case HAL_PIXEL_FORMAT_YV12:
1363 case HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_P_M:
1364 case HAL_PIXEL_FORMAT_EXYNOS_YCrCb_420_SP_M:
1365 case HAL_PIXEL_FORMAT_EXYNOS_YCrCb_420_SP_M_FULL:
1366 case HAL_PIXEL_FORMAT_YCrCb_420_SP:
1367 case HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SP_M:
1368 case HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SP_M_PRIV:
1369 return 1;
1370 case HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SP_M_TILED:
1371 default:
1372 return isRotated(layer) ? 2 : 1;
1373 }
1374 }
1375
1376 void *ExynosMPP::createMPP(int id, int mode, int outputMode, int drm)
1377 {
1378 ATRACE_CALL();
1379 mppFact = new MppFactory();
1380 libmpp = mppFact->CreateMpp(id, mode, outputMode, drm);
1381
1382 return reinterpret_cast<void *>(libmpp);
1383 }
1384
1385 int ExynosMPP::configMPP(void *handle, exynos_mpp_img *src, exynos_mpp_img *dst)
1386 {
1387 ATRACE_CALL();
1388 return libmpp->ConfigMpp(handle, src, dst);
1389 }
1390
1391 int ExynosMPP::runMPP(void *handle, exynos_mpp_img *src, exynos_mpp_img *dst)
1392 {
1393 ATRACE_CALL();
1394 return libmpp->RunMpp(handle, src, dst);
1395 }
1396
1397 int ExynosMPP::stopMPP(void *handle)
1398 {
1399 ATRACE_CALL();
1400 return libmpp->StopMpp(handle);
1401 }
1402
1403 void ExynosMPP::destroyMPP(void *handle)
1404 {
1405 ATRACE_CALL();
1406 libmpp->DestroyMpp(handle);
1407 delete(mppFact);
1408 }
1409
1410 int ExynosMPP::setCSCProperty(void *handle, unsigned int eqAuto, unsigned int fullRange, unsigned int colorspace)
1411 {
1412 return libmpp->SetCSCProperty(handle, eqAuto, fullRange, colorspace);
1413 }
1414
1415 int ExynosMPP::freeMPP(void *handle)
1416 {
1417 ATRACE_CALL();
1418 return libmpp->FreeMpp(handle);
1419 }
1420
1421 int ExynosMPP::setInputCrop(void *handle, exynos_mpp_img *src, exynos_mpp_img *dst)
1422 {
1423 return libmpp->SetInputCrop(handle, src, dst);
1424 }
1425
1426 bool ExynosMPP::bufferChanged(hwc_layer_1_t &layer)
1427 {
1428 private_handle_t *handle = private_handle_t::dynamicCast(layer.handle);
1429 return mSrcConfig.fw != (uint32_t)handle->stride ||
1430 mSrcConfig.fh != (uint32_t)handle->vstride ||
1431 mSrcConfig.format != (uint32_t)handle->format ||
1432 mDstConfig.rot != (uint32_t)layer.transform;
1433 }
1434
1435 bool ExynosMPP::needsReqbufs()
1436 {
1437 return mNeedReqbufs;
1438 }
1439
1440 bool ExynosMPP::inUse()
1441 {
1442 return mGscHandle != NULL;
1443 }
1444
1445 void ExynosMPP::freeBuffers()
1446 {
1447 alloc_device_t* alloc_device = mDisplay->mAllocDevice;
1448 android::List<buffer_handle_t >::iterator it;
1449 android::List<buffer_handle_t >::iterator end;
1450 {
1451 android::Mutex::Autolock lock(mMutex);
1452 it = mFreedBuffers.begin();
1453 end = mFreedBuffers.end();
1454 }
1455 while (it != end) {
1456 buffer_handle_t buffer = (buffer_handle_t)(*it);
1457 alloc_device->free(alloc_device, buffer);
1458 {
1459 android::Mutex::Autolock lock(mMutex);
1460 it = mFreedBuffers.erase(it);
1461 }
1462 }
1463 }
1464
1465 bool BufferFreeThread::threadLoop()
1466 {
1467 while(mRunning) {
1468 {
1469 android::Mutex::Autolock lock(mExynosMPP->mMutex);
1470 while(mExynosMPP->mFreedBuffers.size() == 0) {
1471 mCondition.wait(mExynosMPP->mMutex);
1472 }
1473 }
1474 mExynosMPP->freeBuffers();
1475 }
1476 return true;
1477 }
1478
1479 bool ExynosMPP::isSrcCropAligned(hwc_layer_1_t &layer, bool rotation)
1480 {
1481 return !rotation ||
1482 ((uint32_t)layer.sourceCropf.left % srcXOffsetAlign(layer) == 0 &&
1483 (uint32_t)layer.sourceCropf.top % srcYOffsetAlign(layer) == 0);
1484 }