1 #define ATRACE_TAG ATRACE_TAG_GRAPHICS
3 #include <utils/Trace.h>
5 #include "ExynosHWCUtils.h"
6 #ifdef USES_VIRTUAL_DISPLAY
7 #include "ExynosVirtualDisplay.h"
10 size_t visibleWidth(ExynosMPP
*processor
, hwc_layer_1_t
&layer
, int format
,
14 if (processor
->isProcessingRequired(layer
, format
) && format
!= HAL_PIXEL_FORMAT_RGB_565
)
17 bpp
= formatToBpp(format
);
18 int left
= max(layer
.displayFrame
.left
, 0);
19 int right
= min(layer
.displayFrame
.right
, xres
);
21 return (right
- left
) * bpp
/ 8;
24 ExynosMPP::ExynosMPP()
29 ExynosMPP::ExynosMPP(ExynosDisplay
*display
, int gscIndex
)
32 this->mDisplay
= display
;
33 this->mIndex
= gscIndex
;
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
;
47 mNumAvailableDstBuffers
= NUM_GSC_DST_BUFS
;
50 mLastGSCLayerHandle
= -1;
54 mDoubleOperation
= false;
55 mBufferFreeThread
= new BufferFreeThread(this);
56 mBufferFreeThread
->mRunning
= true;
57 mBufferFreeThread
->run("MPPThread");
60 ExynosMPP::~ExynosMPP()
62 if (mBufferFreeThread
!= NULL
) {
63 mBufferFreeThread
->mRunning
= false;
64 mBufferFreeThread
->requestExitAndWait();
65 delete mBufferFreeThread
;
69 bool ExynosMPP::isM2M()
71 return mGSCMode
== exynos5_gsc_map_t::GSC_M2M
;
74 bool ExynosMPP::isUsingMSC()
76 return (AVAILABLE_GSC_UNITS
[mIndex
] >= 4 && AVAILABLE_GSC_UNITS
[mIndex
] <= 6);
79 bool ExynosMPP::isOTF()
81 return mGSCMode
== exynos5_gsc_map_t::GSC_LOCAL
;
84 void ExynosMPP::setMode(int mode
)
89 void ExynosMPP::free()
92 if (mWaitVsyncCount
> 0) {
97 mDisplay
->mOtfMode
= OTF_OFF
;
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
));
107 mLastGSCLayerHandle
= 0;
109 for (size_t i
= 0; i
< NUM_GSC_DST_BUFS
; i
++) {
110 mDstBufFence
[i
] = -1;
111 mMidBufFence
[i
] = -1;
119 bool ExynosMPP::isSrcConfigChanged(exynos_mpp_img
&c1
, exynos_mpp_img
&c2
)
121 return isDstConfigChanged(c1
, c2
) ||
126 bool ExynosMPP::isFormatSupportedByGsc(int 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
:
149 bool ExynosMPP::formatRequiresGsc(int format
)
151 return (isFormatSupportedByGsc(format
) &&
152 (format
!= HAL_PIXEL_FORMAT_RGBX_8888
) && (format
!= HAL_PIXEL_FORMAT_RGB_565
) &&
153 (format
!= HAL_PIXEL_FORMAT_RGBA_8888
));
156 int ExynosMPP::getDownscaleRatio(int *downNumerator
, int *downDenominator
)
159 *downDenominator
= 0;
163 bool ExynosMPP::isFormatSupportedByGscOtf(int 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
:
183 int ExynosMPP::isProcessingSupported(hwc_layer_1_t
&layer
, int format
,
184 bool local_path
, int downNumerator
, int downDenominator
)
186 if (local_path
&& downNumerator
== 0) {
187 return -eMPPUnsupportedDownScale
;
190 if (isUsingMSC() && local_path
) {
191 return -eMPPUnsupportedHW
;
194 if (!isUsingMSC() && layer
.blending
!= HWC_BLENDING_NONE
)
195 return -eMPPUnsupportedBlending
;
197 private_handle_t
*handle
= private_handle_t::dynamicCast(layer
.handle
);
199 if (isUsingMSC() && handle
&&
200 isFormatRgb(handle
->format
) && !hasAlpha(handle
->format
) &&
201 (layer
.blending
== HWC_BLENDING_PREMULT
))
202 return -eMPPUnsupportedBlending
;
204 int max_w
= maxWidth(layer
);
205 int max_h
= maxHeight(layer
);
206 int min_w
= minWidth(layer
);
207 int min_h
= minHeight(layer
);
216 crop_max_w
= isRotated(layer
) ? 2016 : 4800;
217 crop_max_h
= isRotated(layer
) ? 2016 : 3344;
219 int crop_min_w
= isRotated(layer
) ? 32: 64;
220 int crop_min_h
= isRotated(layer
) ? 64: 32;
227 int srcWidthAlign
= sourceWidthAlign(handle
->format
);
228 int srcHeightAlign
= sourceHeightAlign(handle
->format
);
231 dstAlign
= destinationAlign(HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SP_M
);
233 dstAlign
= destinationAlign(HAL_PIXEL_FORMAT_BGRA_8888
);
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
242 int src_w
= WIDTH(layer
.sourceCropf
), src_h
= HEIGHT(layer
.sourceCropf
);
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
);
249 dest_w
= HEIGHT(layer
.displayFrame
);
250 dest_h
= WIDTH(layer
.displayFrame
);
252 dest_w
= WIDTH(layer
.displayFrame
);
253 dest_h
= HEIGHT(layer
.displayFrame
);
256 if (getDrmMode(handle
->flags
) != NO_DRM
)
257 alignCropAndCenter(dest_w
, dest_h
, NULL
,
258 GSC_DST_CROP_W_ALIGNMENT_RGB888
);
264 /* check whether GSC can handle with local path */
266 if (isFormatRgb(format
) && rot90or270
)
267 return -eMPPUnsupportedRotation
;
269 /* GSC OTF can't handle rot90 or rot270 */
270 if (!rotationSupported(rot90or270
))
271 return -eMPPUnsupportedRotation
;
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.
277 if (layer
.displayFrame
.left
< 0 || layer
.displayFrame
.top
< 0 ||
278 layer
.displayFrame
.right
> mDisplay
->mXres
|| layer
.displayFrame
.bottom
> mDisplay
->mYres
)
279 return -eMPPUnsupportedCoordinate
;
281 /* GSC OTF can't handle GRALLOC_USAGE_PROTECTED layer */
282 if (getDrmMode(handle
->flags
) != NO_DRM
)
283 return -eMPPUnsupportedDRMContents
;
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
;
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
)
332 if (!mDisplay
->mHasDrmSurface
) {
333 need_gsc_op_twice
= false;
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;
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
;
386 bool ExynosMPP::isProcessingRequired(hwc_layer_1_t
&layer
, int format
)
388 return formatRequiresGsc(format
) || isScaled(layer
)
389 || isTransformed(layer
);
392 int ExynosMPP::getAdjustedCrop(int rawSrcSize
, int dstSize
, int format
, bool isVertical __unused
, bool isRotated
)
397 if (dstSize
>= rawSrcSize
|| rawSrcSize
<= dstSize
* FIRST_PRESCALER_THRESHOLD
)
399 else if (rawSrcSize
< dstSize
* SECOND_PRESCALER_THRESHOLD
)
404 if (isFormatRgb(format
)) {
413 return rawSrcSize
- (rawSrcSize
% align
);
416 void ExynosMPP::setupSource(exynos_mpp_img
&src_img
, hwc_layer_1_t
&layer
)
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
;
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
);
435 if (mS3DMode
== S3D_SBS
)
437 if (mS3DMode
== S3D_TB
)
439 if (isFormatYCrCb(src_handle
->format
)) {
440 src_img
.uaddr
= src_handle
->fd2
;
441 src_img
.vaddr
= src_handle
->fd1
;
443 src_img
.uaddr
= src_handle
->fd1
;
444 src_img
.vaddr
= src_handle
->fd2
;
446 if (src_handle
->format
!= HAL_PIXEL_FORMAT_EXYNOS_YCrCb_420_SP_M_FULL
)
447 src_img
.format
= src_handle
->format
;
449 src_img
.format
= HAL_PIXEL_FORMAT_EXYNOS_YCrCb_420_SP_M
;
451 if (layer
.blending
== HWC_BLENDING_COVERAGE
)
452 src_img
.pre_multi
= false;
454 src_img
.pre_multi
= true;
456 src_img
.drmMode
= !!(getDrmMode(src_handle
->flags
) == SECURE_DRM
);
457 src_img
.acquireFenceFd
= layer
.acquireFenceFd
;
460 void ExynosMPP::setupOtfDestination(exynos_mpp_img
&src_img
, exynos_mpp_img
&dst_img
, hwc_layer_1_t
&layer
)
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
;
476 int ExynosMPP::sourceWidthAlign(int format __unused
)
481 int ExynosMPP::sourceHeightAlign(int format __unused
)
486 int ExynosMPP::destinationAlign(int format __unused
)
491 int ExynosMPP::reconfigureOtf(exynos_mpp_img
*src_img
, exynos_mpp_img
*dst_img
)
495 ret
= stopMPP(mGscHandle
);
497 ALOGE("failed to stop gscaler %u", mIndex
);
501 mCountSameConfig
= 0;
505 mGscHandle
= createMPP(AVAILABLE_GSC_UNITS
[mIndex
],
506 GSC_OUTPUT_MODE
, GSC_OUT_FIMD
, false);
508 ALOGE("failed to create gscaler handle");
513 ret
= configMPP(mGscHandle
, src_img
, dst_img
);
515 ALOGE("failed to configure gscaler %u", mIndex
);
522 int ExynosMPP::processOTF(hwc_layer_1_t
&layer
)
525 ALOGV("configuring gscaler %u for memory-to-fimd-localout", mIndex
);
531 exynos_mpp_img src_img
, dst_img
;
532 memset(&src_img
, 0, sizeof(src_img
));
533 memset(&dst_img
, 0, sizeof(dst_img
));
535 setupSource(src_img
, layer
);
536 setupOtfDestination(src_img
, dst_img
, layer
);
538 dstAlign
= destinationAlign(dst_img
.format
);
540 ALOGV("source configuration:");
541 dumpMPPImage(src_img
);
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
);
553 if (isSourceCropChanged(src_img
, mSrcConfig
)) {
554 setInputCrop(mGscHandle
, &src_img
, &dst_img
);
557 ALOGV("destination configuration:");
558 dumpMPPImage(dst_img
);
560 ret
= runMPP(mGscHandle
, &src_img
, &dst_img
);
562 ALOGE("failed to run gscaler %u", mIndex
);
566 memcpy(&mSrcConfig
, &src_img
, sizeof(mSrcConfig
));
567 memcpy(&mDstConfig
, &dst_img
, sizeof(mDstConfig
));
572 if (src_img
.acquireFenceFd
>= 0)
573 close(src_img
.acquireFenceFd
);
575 memset(&mSrcConfig
, 0, sizeof(mSrcConfig
));
576 memset(&mDstConfig
, 0, sizeof(mDstConfig
));
581 bool ExynosMPP::setupDoubleOperation(exynos_mpp_img
&src_img
, exynos_mpp_img
&mid_img
, hwc_layer_1_t
&layer
)
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
);
592 dest_w
= HEIGHT(layer
.displayFrame
);
593 dest_h
= WIDTH(layer
.displayFrame
);
595 dest_w
= WIDTH(layer
.displayFrame
);
596 dest_h
= HEIGHT(layer
.displayFrame
);
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;
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;
607 if (need_gsc_op_twice
) {
611 int mid_w
= 0, mid_h
= 0;
613 if (need_unscaled_csc
) {
618 mid_w
= HEIGHT(layer
.displayFrame
);
619 mid_h
= WIDTH(layer
.displayFrame
);
621 mid_w
= WIDTH(layer
.displayFrame
);
622 mid_h
= HEIGHT(layer
.displayFrame
);
625 if (WIDTH(layer
.sourceCropf
) * max_upscale
< mid_w
)
626 mid_img
.w
= (((mid_w
+ 7) / 8) + 1) & ~1;
630 if (HEIGHT(layer
.sourceCropf
) * max_upscale
< mid_h
)
631 mid_img
.h
= (((mid_h
+ 7) / 8) + 1) & ~1;
635 mid_img
.drmMode
= src_img
.drmMode
;
636 mid_img
.format
= HAL_PIXEL_FORMAT_EXYNOS_YCrCb_420_SP_M
;
638 if (layer
.blending
== HWC_BLENDING_PREMULT
|| layer
.blending
== HWC_BLENDING_COVERAGE
)
639 mid_img
.pre_multi
= false;
641 mid_img
.pre_multi
= true;
643 mid_img
.mem_type
= GSC_MEM_DMABUF
;
644 mid_img
.narrowRgb
= !isFormatRgb(src_handle
->format
);
647 return need_gsc_op_twice
;
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
)
653 private_handle_t
*src_handle
= private_handle_t::dynamicCast(layer
.handle
);
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
;
662 if (layer
.blending
== HWC_BLENDING_PREMULT
|| layer
.blending
== HWC_BLENDING_COVERAGE
)
663 dst_img
.pre_multi
= false;
665 dst_img
.pre_multi
= true;
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;
671 dst_img
.narrowRgb
= !isFormatRgb(src_handle
->format
);
673 alignCropAndCenter(dst_img
.w
, dst_img
.h
, sourceCrop
,
674 GSC_DST_CROP_W_ALIGNMENT_RGB888
);
677 int ExynosMPP::reallocateBuffers(private_handle_t
*src_handle
, exynos_mpp_img
&dst_img
, exynos_mpp_img
&mid_img
, bool need_gsc_op_twice
)
680 alloc_device_t
* alloc_device
= mDisplay
->mAllocDevice
;
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) |
689 GRALLOC_USAGE_HW_COMPOSER
;
691 #ifdef USE_FB_PHY_LINEAR
692 usage
|= GRALLOC_USAGE_PROTECTED
;
693 usage
&= ~GRALLOC_USAGE_PRIVATE_NONSECURE
;
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
;
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
);
712 int dstAlign
= destinationAlign(dst_img
.format
);
713 w
= ALIGN(mDisplay
->mXres
, dstAlign
);
714 h
= ALIGN(mDisplay
->mYres
, dstAlign
);
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
;
724 if (mDstBufFence
[i
] >= 0) {
725 close(mDstBufFence
[i
]);
726 mDstBufFence
[i
] = -1;
729 if (mMidBuffers
[i
] != NULL
) {
730 android::Mutex::Autolock
lock(mMutex
);
731 mFreedBuffers
.push_back(mMidBuffers
[i
]);
732 mMidBuffers
[i
] = NULL
;
735 if (mMidBufFence
[i
] >= 0) {
736 close(mMidBufFence
[i
]);
737 mMidBufFence
[i
] = -1;
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
;
746 mNumAvailableDstBuffers
= NUM_GSC_DST_BUFS
;
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
],
754 ALOGE("failed to allocate destination buffer(%dx%d): %s", w
, h
,
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
],
764 ALOGE("failed to allocate intermediate buffer(%dx%d): %s", mid_img
.w
, mid_img
.h
,
771 android::Mutex::Autolock
lock(mMutex
);
772 mBufferFreeThread
->mCondition
.signal();
777 #ifdef USES_VIRTUAL_DISPLAY
778 int ExynosMPP::processM2M(hwc_layer_1_t
&layer
, int dst_format
, hwc_frect_t
*sourceCrop
, bool isNeedBufferAlloc
)
780 int ExynosMPP::processM2M(hwc_layer_1_t
&layer
, int dst_format
, hwc_frect_t
*sourceCrop
)
784 ALOGV("configuring gscaler %u for memory-to-memory", AVAILABLE_GSC_UNITS
[mIndex
]);
786 #ifdef USES_VIRTUAL_DISPLAY
787 alloc_device_t
* alloc_device
= mDisplay
->mAllocDevice
;
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
;
797 if (dst_format
!= HAL_PIXEL_FORMAT_RGB_565
)
798 dst_format
= HAL_PIXEL_FORMAT_BGRA_8888
;
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
));
807 hwc_frect_t sourceCropTemp
;
809 sourceCrop
= &sourceCropTemp
;
811 setupSource(src_img
, layer
);
812 src_img
.mem_type
= GSC_MEM_DMABUF
;
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
;
819 bool need_gsc_op_twice
= setupDoubleOperation(src_img
, mid_img
, layer
);
821 setupM2MDestination(src_img
, dst_img
, dst_format
, layer
, sourceCrop
);
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
;
832 ALOGV("source configuration:");
833 dumpMPPImage(src_img
);
835 bool reconfigure
= isSrcConfigChanged(src_img
, mSrcConfig
) ||
836 isDstConfigChanged(dst_img
, mDstConfig
);
838 #ifdef USES_VIRTUAL_DISPLAY
839 if (isNeedBufferAlloc
) {
841 bool realloc
= mDstConfig
.fw
<= 0 || formatToBpp(mDstConfig
.format
) != formatToBpp(dst_format
);
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
)
851 if (need_gsc_op_twice
&& isSrcConfigChanged(mid_img
, mMidConfig
))
854 if (need_gsc_op_twice
&& !mDoubleOperation
)
856 mDoubleOperation
= need_gsc_op_twice
;
858 if (reconfigure
&& realloc
) {
859 if ((ret
= reallocateBuffers(src_handle
, dst_img
, mid_img
, need_gsc_op_twice
)) < 0)
863 mLastGSCLayerHandle
= 0;
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
);
871 layer
.releaseFenceFd
= -1;
872 layer
.acquireFenceFd
= -1;
873 mDstConfig
.releaseFenceFd
= -1;
875 mCurrentBuf
= (mCurrentBuf
+ mNumAvailableDstBuffers
- 1) % mNumAvailableDstBuffers
;
878 mLastGSCLayerHandle
= (ptrdiff_t)layer
.handle
;
880 #ifdef USES_VIRTUAL_DISPLAY
882 if (reconfigure
&& need_gsc_op_twice
) {
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
;
891 if (mMidBufFence
[0] >= 0) {
892 close(mMidBufFence
[0]);
893 mMidBufFence
[0] = -1;
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],
900 ALOGE("failed to allocate intermediate buffer(%dx%d): %s", mid_img
.w
, mid_img
.h
,
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
);
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
;
922 mid_img
.uaddr
= mid_handle
->fd1
;
923 mid_img
.vaddr
= mid_handle
->fd2
;
925 //mid_img.acquireFenceFd = -1;
927 ALOGV("mid configuration:");
928 dumpMPPImage(mid_img
);
931 dst_buf
= mDstBuffers
[mCurrentBuf
];
932 dst_handle
= private_handle_t::dynamicCast(dst_buf
);
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;
942 ALOGV("destination configuration:");
943 dumpMPPImage(dst_img
);
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
);
952 ALOGV("reusing open gscaler %u", AVAILABLE_GSC_UNITS
[mIndex
]);
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
));
958 ALOGE("failed to create gscaler handle");
964 if (!need_gsc_op_twice
)
965 memcpy(&mid_img
, &dst_img
, sizeof(exynos_mpp_img
));
967 /* src -> mid or src->dest */
968 if (reconfigure
|| need_gsc_op_twice
) {
969 ret
= stopMPP(mGscHandle
);
971 ALOGE("failed to stop gscaler %u", mIndex
);
975 ret
= setCSCProperty(mGscHandle
, 0, !mid_img
.narrowRgb
, 1);
976 ret
= configMPP(mGscHandle
, &src_img
, &mid_img
);
978 ALOGE("failed to configure gscaler %u", mIndex
);
983 ret
= runMPP(mGscHandle
, &src_img
, &mid_img
);
985 ALOGE("failed to run gscaler %u", mIndex
);
990 if (need_gsc_op_twice
) {
991 ret
= stopMPP(mGscHandle
);
993 ALOGE("failed to stop gscaler %u", mIndex
);
997 mid_img
.acquireFenceFd
= mid_img
.releaseFenceFd
;
999 ret
= setCSCProperty(mGscHandle
, 0, !dst_img
.narrowRgb
, 1);
1000 ret
= configMPP(mGscHandle
, &mid_img
, &dst_img
);
1002 ALOGE("failed to configure gscaler %u", mIndex
);
1003 goto err_gsc_config
;
1006 ret
= runMPP(mGscHandle
, &mid_img
, &dst_img
);
1008 ALOGE("failed to run gscaler %u", mIndex
);
1009 goto err_gsc_config
;
1011 mMidBufFence
[mCurrentBuf
] = mid_img
.releaseFenceFd
;
1014 mSrcConfig
= src_img
;
1015 mMidConfig
= mid_img
;
1017 if (need_gsc_op_twice
) {
1018 mDstConfig
= dst_img
;
1020 mDstConfig
= mid_img
;
1023 layer
.releaseFenceFd
= src_img
.releaseFenceFd
;
1029 destroyMPP(mGscHandle
);
1033 if (src_img
.acquireFenceFd
>= 0)
1034 close(src_img
.acquireFenceFd
);
1035 #ifdef USES_VIRTUAL_DISPLAY
1036 if (isNeedBufferAlloc
) {
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
;
1044 if (mDstBufFence
[i
] >= 0) {
1045 close(mDstBufFence
[i
]);
1046 mDstBufFence
[i
] = -1;
1048 if (mMidBuffers
[i
]) {
1049 android::Mutex::Autolock
lock(mMutex
);
1050 mFreedBuffers
.push_back(mMidBuffers
[i
]);
1051 mMidBuffers
[i
] = NULL
;
1053 if (mMidBufFence
[i
] >= 0) {
1054 close(mMidBufFence
[i
]);
1055 mMidBufFence
[i
] = -1;
1058 #ifdef USES_VIRTUAL_DISPLAY
1060 if (mMidBuffers
[0]) {
1061 android::Mutex::Autolock
lock(mMutex
);
1062 mFreedBuffers
.push_back(mMidBuffers
[0]);
1063 mMidBuffers
[0] = NULL
;
1065 if (mMidBufFence
[0] >= 0) {
1066 close(mMidBufFence
[0]);
1067 mMidBufFence
[0] = -1;
1072 android::Mutex::Autolock
lock(mMutex
);
1073 mBufferFreeThread
->mCondition
.signal();
1075 memset(&mSrcConfig
, 0, sizeof(mSrcConfig
));
1076 memset(&mDstConfig
, 0, sizeof(mDstConfig
));
1077 memset(&mMidConfig
, 0, sizeof(mMidConfig
));
1081 void ExynosMPP::cleanupM2M()
1086 void ExynosMPP::cleanupM2M(bool noFenceWait
)
1092 ALOGV("closing gscaler %u", AVAILABLE_GSC_UNITS
[mIndex
]);
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");
1101 if (mMidBufFence
[i
] >= 0)
1102 if (sync_wait(mMidBufFence
[i
], 1000) < 0)
1103 ALOGE("sync_wait error");
1108 stopMPP(mGscHandle
);
1109 destroyMPP(mGscHandle
);
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
]);
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
;
1123 if (mMidBufFence
[i
] >= 0)
1124 close(mMidBufFence
[i
]);
1127 android::Mutex::Autolock
lock(mMutex
);
1128 mBufferFreeThread
->mCondition
.signal();
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
));
1140 mLastGSCLayerHandle
= 0;
1142 for (size_t i
= 0; i
< NUM_GSC_DST_BUFS
; i
++) {
1143 mDstBufFence
[i
] = -1;
1144 mMidBufFence
[i
] = -1;
1148 void ExynosMPP::cleanupOTF()
1151 stopMPP(mGscHandle
);
1152 freeMPP(mGscHandle
);
1155 mNeedReqbufs
= false;
1156 mWaitVsyncCount
= 0;
1157 mDisplay
->mOtfMode
= OTF_OFF
;
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
));
1167 mLastGSCLayerHandle
= 0;
1169 for (size_t i
= 0; i
< NUM_GSC_DST_BUFS
; i
++) {
1170 mDstBufFence
[i
] = -1;
1171 mMidBufFence
[i
] = -1;
1175 bool ExynosMPP::rotationSupported(bool rotation
)
1180 bool ExynosMPP::paritySupported(int w
, int h
)
1182 return (w
% 2 == 0) && (h
% 2 == 0);
1185 bool ExynosMPP::isDstConfigChanged(exynos_mpp_img
&c1
, exynos_mpp_img
&c2
)
1187 return c1
.x
!= c2
.x
||
1191 c1
.format
!= c2
.format
||
1193 c1
.narrowRgb
!= c2
.narrowRgb
||
1194 c1
.cacheable
!= c2
.cacheable
||
1195 c1
.pre_multi
!= c2
.pre_multi
||
1196 c1
.drmMode
!= c2
.drmMode
;
1199 bool ExynosMPP::isSourceCropChanged(exynos_mpp_img
&c1 __unused
, exynos_mpp_img
&c2 __unused
)
1204 bool ExynosMPP::isPerFrameSrcChanged(exynos_mpp_img
&c1 __unused
, exynos_mpp_img
&c2 __unused
)
1209 bool ExynosMPP::isPerFrameDstChanged(exynos_mpp_img
&c1 __unused
, exynos_mpp_img
&c2 __unused
)
1214 bool ExynosMPP::isReallocationRequired(int w
, int h
, exynos_mpp_img
&c1
, exynos_mpp_img
&c2
)
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
;
1222 uint32_t ExynosMPP::halFormatToMPPFormat(int 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
;
1236 int ExynosMPP::minWidth(hwc_layer_1_t
&layer
)
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
:
1254 return isRotated(layer
) ? 32 : 64;
1258 int ExynosMPP::minHeight(hwc_layer_1_t
&layer
)
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
:
1276 return isRotated(layer
) ? 64 : 32;
1280 int ExynosMPP::maxWidth(hwc_layer_1_t
&layer
)
1282 private_handle_t
*handle
= private_handle_t::dynamicCast(layer
.handle
);
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
:
1300 case HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SP_M_TILED
:
1306 int ExynosMPP::maxHeight(hwc_layer_1_t
&layer
)
1308 private_handle_t
*handle
= private_handle_t::dynamicCast(layer
.handle
);
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
:
1326 case HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SP_M_TILED
:
1332 int ExynosMPP::srcXOffsetAlign(hwc_layer_1_t
&layer
)
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
:
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
:
1354 int ExynosMPP::srcYOffsetAlign(hwc_layer_1_t
&layer
)
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
:
1370 case HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SP_M_TILED
:
1372 return isRotated(layer
) ? 2 : 1;
1376 void *ExynosMPP::createMPP(int id
, int mode
, int outputMode
, int drm
)
1379 mppFact
= new MppFactory();
1380 libmpp
= mppFact
->CreateMpp(id
, mode
, outputMode
, drm
);
1382 return reinterpret_cast<void *>(libmpp
);
1385 int ExynosMPP::configMPP(void *handle
, exynos_mpp_img
*src
, exynos_mpp_img
*dst
)
1388 return libmpp
->ConfigMpp(handle
, src
, dst
);
1391 int ExynosMPP::runMPP(void *handle
, exynos_mpp_img
*src
, exynos_mpp_img
*dst
)
1394 return libmpp
->RunMpp(handle
, src
, dst
);
1397 int ExynosMPP::stopMPP(void *handle
)
1400 return libmpp
->StopMpp(handle
);
1403 void ExynosMPP::destroyMPP(void *handle
)
1406 libmpp
->DestroyMpp(handle
);
1410 int ExynosMPP::setCSCProperty(void *handle
, unsigned int eqAuto
, unsigned int fullRange
, unsigned int colorspace
)
1412 return libmpp
->SetCSCProperty(handle
, eqAuto
, fullRange
, colorspace
);
1415 int ExynosMPP::freeMPP(void *handle
)
1418 return libmpp
->FreeMpp(handle
);
1421 int ExynosMPP::setInputCrop(void *handle
, exynos_mpp_img
*src
, exynos_mpp_img
*dst
)
1423 return libmpp
->SetInputCrop(handle
, src
, dst
);
1426 bool ExynosMPP::bufferChanged(hwc_layer_1_t
&layer
)
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
;
1435 bool ExynosMPP::needsReqbufs()
1437 return mNeedReqbufs
;
1440 bool ExynosMPP::inUse()
1442 return mGscHandle
!= NULL
;
1445 void ExynosMPP::freeBuffers()
1447 alloc_device_t
* alloc_device
= mDisplay
->mAllocDevice
;
1448 android::List
<buffer_handle_t
>::iterator it
;
1449 android::List
<buffer_handle_t
>::iterator end
;
1451 android::Mutex::Autolock
lock(mMutex
);
1452 it
= mFreedBuffers
.begin();
1453 end
= mFreedBuffers
.end();
1456 buffer_handle_t buffer
= (buffer_handle_t
)(*it
);
1457 alloc_device
->free(alloc_device
, buffer
);
1459 android::Mutex::Autolock
lock(mMutex
);
1460 it
= mFreedBuffers
.erase(it
);
1465 bool BufferFreeThread::threadLoop()
1469 android::Mutex::Autolock
lock(mExynosMPP
->mMutex
);
1470 while(mExynosMPP
->mFreedBuffers
.size() == 0) {
1471 mCondition
.wait(mExynosMPP
->mMutex
);
1474 mExynosMPP
->freeBuffers();
1479 bool ExynosMPP::isSrcCropAligned(hwc_layer_1_t
&layer
, bool rotation
)
1482 ((uint32_t)layer
.sourceCropf
.left
% srcXOffsetAlign(layer
) == 0 &&
1483 (uint32_t)layer
.sourceCropf
.top
% srcYOffsetAlign(layer
) == 0);