1 #define ATRACE_TAG ATRACE_TAG_GRAPHICS
4 #define LOG_TAG "virtualdisplay"
5 #include "exynos_format.h"
7 #include "ExynosHWCUtils.h"
8 #include "ExynosMPPModule.h"
9 #include "ExynosVirtualDisplay.h"
11 #ifdef USES_DISABLE_COMPOSITIONTYPE_GLES
12 #include "ExynosPrimaryDisplay.h"
15 #include <utils/Trace.h>
17 #ifdef USE_VIDEO_EXT_FOR_WFD_DRM
18 #define WAIT_COUNT_FOR_ISOLATION 50
21 ExynosVirtualDisplay::ExynosVirtualDisplay(struct exynos5_hwc_composer_device_1_t
*pdev
) :
22 ExynosDisplay(EXYNOS_VIRTUAL_DISPLAY
, pdev
),
28 mIsRotationState(false),
30 mDeviceOrientation(0),
31 mFrameBufferTargetTransform(0),
32 mCompositionType(COMPOSITION_GLES
),
33 mPrevCompositionType(COMPOSITION_GLES
),
34 mGLESFormat(HAL_PIXEL_FORMAT_RGBA_8888
),
35 mSinkUsage(GRALLOC_USAGE_HW_COMPOSER
),
38 #ifdef USE_VIDEO_EXT_FOR_WFD_DRM
40 mSMemProtected(false),
42 mFlagIONBufferAllocated(false)
49 #ifdef USES_DISABLE_COMPOSITIONTYPE_GLES
50 mExternalMPPforCSC
= new ExynosMPPModule(this, MPP_MSC
, 0);
51 mExternalMPPforCSC
->setAllocDevice(pdev
->primaryDisplay
->mAllocDevice
);
55 mFBTargetLayer
= NULL
;
56 memset(mFBLayer
, 0x0, sizeof(hwc_layer_1_t
*) * NUM_FRAME_BUFFER
);
59 #ifdef USES_VDS_BGRA8888
60 mForceDoubleOperation
= false;
61 mExternalMPPDstFormat
= HAL_PIXEL_FORMAT_RGBA_8888
;
64 #ifdef USE_VIDEO_EXT_FOR_WFD_DRM
65 mSMemFd
= open(SMEM_PATH
, O_RDWR
);
67 ALOGE("Fail to open smem_fd %s, error(%d)", SMEM_PATH
, mSMemFd
);
69 ALOGI("Open %s", SMEM_PATH
);
71 mReserveMemFd
= open(HDMI_RESERVE_MEM_DEV_NAME
, O_RDWR
);
72 if (mReserveMemFd
< 0)
73 ALOGE("Fail to open hdmi_reserve_mem_fd %s, error(%d)", HDMI_RESERVE_MEM_DEV_NAME
, mReserveMemFd
);
75 ALOGI("Open %s", HDMI_RESERVE_MEM_DEV_NAME
);
79 ExynosVirtualDisplay::~ExynosVirtualDisplay()
81 #ifdef USE_VIDEO_EXT_FOR_WFD_DRM
84 if (mReserveMemFd
> 0)
89 void ExynosVirtualDisplay::allocateLayerInfos(hwc_display_contents_1_t
* contents
)
91 ExynosDisplay::allocateLayerInfos(contents
);
95 void ExynosVirtualDisplay::setSinkBufferUsage()
97 ALOGV("setSinkBufferUsage() mSinkUsage 0x%x, mIsSecureDRM %d, mIsNormalDRM %d",
98 mSinkUsage
, mIsSecureDRM
, mIsNormalDRM
);
99 mSinkUsage
= GRALLOC_USAGE_HW_COMPOSER
;
102 mSinkUsage
|= GRALLOC_USAGE_SW_READ_NEVER
|
103 GRALLOC_USAGE_SW_WRITE_NEVER
|
104 GRALLOC_USAGE_PROTECTED
;
105 #ifdef USE_VIDEO_EXT_FOR_WFD_DRM
106 if (mReserveMemFd
> 0) {
107 mSinkUsage
|= GRALLOC_USAGE_VIDEO_EXT
;
108 if (!mSMemProtected
) {
109 setMemoryProtection(1);
110 mSMemProtected
= true;
114 } else if (mIsNormalDRM
)
115 mSinkUsage
|= GRALLOC_USAGE_PRIVATE_NONSECURE
;
117 #ifdef USE_VIDEO_EXT_FOR_WFD_DRM
118 if (mReserveMemFd
> 0 && !mIsSecureDRM
&& mSMemProtected
) {
119 setMemoryProtection(0);
120 mSMemProtected
= false;
124 ALOGV("Sink Buffer's Usage: 0x%x", mSinkUsage
);
127 int ExynosVirtualDisplay::prepare(hwc_display_contents_1_t
* contents
)
130 ALOGV("prepare %u layers for virtual, outbuf %p", contents
->numHwLayers
, contents
->outbuf
);
133 mCompositionType
= COMPOSITION_GLES
;
134 mOverlayLayer
= NULL
;
135 mFBTargetLayer
= NULL
;
138 determineSkipLayer(contents
);
140 /* determine composition type */
141 for (size_t i
= 0; i
< contents
->numHwLayers
; i
++) {
142 hwc_layer_1_t
&layer
= contents
->hwLayers
[i
];
144 if (layer
.compositionType
== HWC_FRAMEBUFFER
) {
149 private_handle_t
*h
= private_handle_t::dynamicCast(layer
.handle
);
150 ALOGV("FB layer %d f=%x, w=%d, h=%d, s=%d, vs=%d, "
151 "{%.1f,%.1f,%.1f,%.1f}, {%d,%d,%d,%d}"
152 "type=%d, flags=%08x, handle=%p, tr=%02x, blend=%04x",
153 i
, h
->format
, h
->width
, h
->height
, h
->stride
, h
->vstride
,
154 layer
.sourceCropf
.left
, layer
.sourceCropf
.top
,
155 layer
.sourceCropf
.right
, layer
.sourceCropf
.bottom
,
156 layer
.displayFrame
.left
, layer
.displayFrame
.top
,
157 layer
.displayFrame
.right
, layer
.displayFrame
.bottom
,
158 layer
.compositionType
, layer
.flags
, layer
.handle
, layer
.transform
, layer
.blending
);
161 if (layer
.compositionType
== HWC_OVERLAY
) {
165 if (layer
.flags
& HWC_SKIP_RENDERING
) {
166 layer
.releaseFenceFd
= layer
.acquireFenceFd
;
170 private_handle_t
*h
= private_handle_t::dynamicCast(layer
.handle
);
171 ALOGV("Overlay layer %d f=%x, w=%d, h=%d, s=%d, vs=%d, "
172 "{%.1f,%.1f,%.1f,%.1f}, {%d,%d,%d,%d}"
173 "type=%d, flags=%08x, handle=%p, tr=%02x, blend=%04x",
174 i
, h
->format
, h
->width
, h
->height
, h
->stride
, h
->vstride
,
175 layer
.sourceCropf
.left
, layer
.sourceCropf
.top
,
176 layer
.sourceCropf
.right
, layer
.sourceCropf
.bottom
,
177 layer
.displayFrame
.left
, layer
.displayFrame
.top
,
178 layer
.displayFrame
.right
, layer
.displayFrame
.bottom
,
179 layer
.compositionType
, layer
.flags
, layer
.handle
, layer
.transform
, layer
.blending
);
181 mOverlayLayer
= &layer
;
185 if (layer
.compositionType
== HWC_FRAMEBUFFER_TARGET
) {
189 private_handle_t
*h
= private_handle_t::dynamicCast(layer
.handle
);
190 ALOGV("FB target layer %d f=%x, w=%d, h=%d, s=%d, vs=%d, "
191 "{%.1f,%.1f,%.1f,%.1f}, {%d,%d,%d,%d}"
192 "type=%d, flags=%08x, handle=%p, tr=%02x, blend=%04x",
193 i
, h
->format
, h
->width
, h
->height
, h
->stride
, h
->vstride
,
194 layer
.sourceCropf
.left
, layer
.sourceCropf
.top
,
195 layer
.sourceCropf
.right
, layer
.sourceCropf
.bottom
,
196 layer
.displayFrame
.left
, layer
.displayFrame
.top
,
197 layer
.displayFrame
.right
, layer
.displayFrame
.bottom
,
198 layer
.compositionType
, layer
.flags
, layer
.handle
, layer
.transform
, layer
.blending
);
200 mFBTargetLayer
= &layer
;
205 if (mOverlayLayer
&& (mNumFB
> 0))
206 mCompositionType
= COMPOSITION_MIXED
;
207 else if (mOverlayLayer
|| mIsRotationState
)
208 mCompositionType
= COMPOSITION_HWC
;
209 ALOGV("mCompositionType 0x%x, mPrevCompositionType 0x%x, overlay_layer 0x%p, mNumFB %d",
210 mCompositionType
, mPrevCompositionType
, mOverlayLayer
, mNumFB
);
212 if (mCompositionType
== COMPOSITION_GLES
)
216 #ifdef USES_DISABLE_COMPOSITIONTYPE_GLES
217 if (mCompositionType
== COMPOSITION_GLES
) {
218 mHwc
->mVirtualDisplayRect
.left
= 0;
219 mHwc
->mVirtualDisplayRect
.top
= 0;
220 mHwc
->mVirtualDisplayRect
.width
= mWidth
;
221 mHwc
->mVirtualDisplayRect
.height
= mHeight
;
222 mCompositionType
= COMPOSITION_MIXED
;
226 #ifdef USES_VDS_BGRA8888
227 if (mCompositionType
!= COMPOSITION_GLES
&& contents
->outbuf
) {
228 private_handle_t
*outbuf_handle
= private_handle_t::dynamicCast(contents
->outbuf
);
230 mGLESFormat
= outbuf_handle
->format
;
235 setSinkBufferUsage();
240 void ExynosVirtualDisplay::configureHandle(private_handle_t
*handle
, size_t index
,
241 hwc_layer_1_t
&layer
, int fence_fd
, decon_win_config
&cfg
)
243 ExynosDisplay::configureHandle(handle
, index
, layer
, fence_fd
, cfg
);
244 #ifdef USES_VDS_BGRA8888
245 if (mForceDoubleOperation
== true && handle
->format
== HAL_PIXEL_FORMAT_RGBA_8888
)
246 cfg
.format
= halFormatToS3CFormat(HAL_PIXEL_FORMAT_BGRA_8888
);
250 void ExynosVirtualDisplay::configureWriteBack(hwc_display_contents_1_t __unused
*contents
,
251 decon_win_config_data __unused
&win_data
)
255 int ExynosVirtualDisplay::postFrame(hwc_display_contents_1_t
* contents
)
257 #ifdef USES_VIRTUAL_DISPLAY_DECON_EXT_WB
259 struct decon_win_config_data win_data
;
260 struct decon_win_config
*config
= win_data
.config
;
262 int tot_ovly_wins
= 0;
263 bool hasSecureLayer
= false;
265 memset(mLastHandles
, 0, sizeof(mLastHandles
));
266 memset(mLastMPPMap
, 0, sizeof(mLastMPPMap
));
267 memset(config
, 0, sizeof(win_data
.config
));
269 if (contents
->outbuf
) {
270 configureWriteBack(contents
, win_data
);
273 for (size_t i
= 0; i
< NUM_HW_WINDOWS
; i
++) {
274 config
[i
].fence_fd
= -1;
275 mLastMPPMap
[i
].internal_mpp
.type
= -1;
276 mLastMPPMap
[i
].external_mpp
.type
= -1;
279 for (size_t i
= 0; i
< contents
->numHwLayers
; i
++) {
280 hwc_layer_1_t
&layer
= contents
->hwLayers
[i
];
281 private_handle_t
*handle
= NULL
;
282 if (layer
.handle
!= NULL
)
283 handle
= private_handle_t::dynamicCast(layer
.handle
);
284 int32_t window_index
= mLayerInfos
[i
]->mWindowIndex
+ DECON_EXT_BASE_WINDOW
;
286 if ((layer
.flags
& HWC_SKIP_RENDERING
) || handle
== NULL
||
287 ((layer
.compositionType
== HWC_OVERLAY
) &&
288 ((window_index
< 0) || (window_index
> MAX_DECON_WIN
)))) {
289 if (layer
.acquireFenceFd
>= 0)
290 close(layer
.acquireFenceFd
);
291 layer
.acquireFenceFd
= -1;
292 layer
.releaseFenceFd
= -1;
294 if ((window_index
< 0) || (window_index
> MAX_DECON_WIN
)) {
295 android::String8 result
;
296 ALOGW("window of layer %d was not assigned (window_index: %d)", i
, window_index
);
297 dumpContents(result
, contents
);
298 ALOGW(result
.string());
300 dumpLayerInfo(result
);
301 ALOGW(result
.string());
307 if ((layer
.compositionType
== HWC_OVERLAY
) ||
308 (mFbNeeded
== true && layer
.compositionType
== HWC_FRAMEBUFFER_TARGET
)) {
309 mLastHandles
[window_index
] = layer
.handle
;
311 if ((getDrmMode(handle
->flags
) == SECURE_DRM
) && layer
.compositionType
!= HWC_FRAMEBUFFER_TARGET
) {
312 config
[window_index
].protection
= 1;
313 hasSecureLayer
= true;
316 config
[window_index
].protection
= 0;
318 if (mLayerInfos
[i
]->mInternalMPP
!= NULL
) {
319 mLastMPPMap
[window_index
].internal_mpp
.type
= mLayerInfos
[i
]->mInternalMPP
->mType
;
320 mLastMPPMap
[window_index
].internal_mpp
.index
= mLayerInfos
[i
]->mInternalMPP
->mIndex
;
322 if (mLayerInfos
[i
]->mExternalMPP
!= NULL
) {
323 mLastMPPMap
[window_index
].external_mpp
.type
= mLayerInfos
[i
]->mExternalMPP
->mType
;
324 mLastMPPMap
[window_index
].external_mpp
.index
= mLayerInfos
[i
]->mExternalMPP
->mIndex
;
325 if (postMPPM2M(layer
, config
, window_index
, i
) < 0)
328 configureOverlay(&layer
, i
, config
[window_index
]);
331 if (window_index
== 0 && config
[window_index
].blending
!= DECON_BLENDING_NONE
) {
332 ALOGV("blending not supported on window 0; forcing BLENDING_NONE");
333 config
[window_index
].blending
= DECON_BLENDING_NONE
;
337 for (size_t i
= 0; i
< NUM_HW_WINDOWS
; i
++) {
338 ALOGV("window %u configuration:", i
);
339 dumpConfig(config
[i
]);
342 /* This should be enabled */
344 if (this->mVirtualOverlayFlag
) {
345 handleStaticLayers(contents
, win_data
, tot_ovly_wins
);
349 if (mIsSecureDRM
!= hasSecureLayer
) {
350 ALOGW("secure state mismatch (mIsSecureDRM: %d, hasSecureLayer: %d)", mIsSecureDRM
, hasSecureLayer
);
351 private_handle_t
*outbuf_handle
= private_handle_t::dynamicCast(contents
->outbuf
);
353 ALOGW("outbuf format: 0x%x, mCompositionType: %d", outbuf_handle
->format
, mCompositionType
);
356 int ret
= winconfigIoctl(&win_data
);
357 ALOGV("ExynosDisplay::postFrame() ioctl(S3CFB_WIN_CONFIG) ret %d", ret
);
359 for (size_t i
= 0; i
< NUM_HW_WINDOWS
; i
++)
360 if (config
[i
].fence_fd
!= -1)
361 close(config
[i
].fence_fd
);
363 ALOGE("ioctl S3CFB_WIN_CONFIG failed: %s", strerror(errno
));
366 if (contents
->numHwLayers
== 1) {
367 hwc_layer_1_t
&layer
= contents
->hwLayers
[0];
368 if (layer
.acquireFenceFd
>= 0)
369 close(layer
.acquireFenceFd
);
372 memcpy(&(this->mLastConfigData
), &win_data
, sizeof(win_data
));
374 if (!this->mVirtualOverlayFlag
)
375 this->mLastFbWindow
= mFbWindow
;
377 return win_data
.fence
;
383 void ExynosVirtualDisplay::processGles(hwc_display_contents_1_t
* contents
)
385 ALOGV("processGles, mFBTargetLayer->acquireFenceFd %d, mFBTargetLayer->releaseFenceFd %d, contents->outbufAcquireFenceFd %d",
386 mFBTargetLayer
->acquireFenceFd
, mFBTargetLayer
->releaseFenceFd
, contents
->outbufAcquireFenceFd
);
388 if (mFBTargetLayer
!= NULL
&& mFBTargetLayer
->acquireFenceFd
>= 0)
389 contents
->retireFenceFd
= mFBTargetLayer
->acquireFenceFd
;
391 if (contents
->outbufAcquireFenceFd
>= 0) {
392 close(contents
->outbufAcquireFenceFd
);
393 contents
->outbufAcquireFenceFd
= -1;
397 void ExynosVirtualDisplay::processHwc(hwc_display_contents_1_t
* contents
)
399 ALOGV("processHwc, mFBTargetLayer->acquireFenceFd %d, mFBTargetLayer->releaseFenceFd %d, contents->outbufAcquireFenceFd %d",
400 mFBTargetLayer
->acquireFenceFd
, mFBTargetLayer
->releaseFenceFd
, contents
->outbufAcquireFenceFd
);
402 ExynosDisplay::set(contents
);
404 if (contents
->outbufAcquireFenceFd
>= 0) {
405 close(contents
->outbufAcquireFenceFd
);
406 contents
->outbufAcquireFenceFd
= -1;
410 void ExynosVirtualDisplay::processMixed(hwc_display_contents_1_t
* contents
)
412 ALOGV("processMixed, mFBTargetLayer->acquireFenceFd %d, mFBTargetLayer->releaseFenceFd %d, contents->outbufAcquireFenceFd %d",
413 mFBTargetLayer
->acquireFenceFd
, mFBTargetLayer
->releaseFenceFd
, contents
->outbufAcquireFenceFd
);
415 ExynosDisplay::set(contents
);
417 if (contents
->outbufAcquireFenceFd
>= 0) {
418 close(contents
->outbufAcquireFenceFd
);
419 contents
->outbufAcquireFenceFd
= -1;
423 int ExynosVirtualDisplay::set(hwc_display_contents_1_t
* contents
)
425 ALOGV("set %u layers for virtual, mCompositionType %d, contents->outbuf %p",
426 contents
->numHwLayers
, mCompositionType
, contents
->outbuf
);
427 mOverlayLayer
= NULL
;
428 mFBTargetLayer
= NULL
;
430 int IsNormalDRMWithSkipLayer
= false;
432 private_handle_t
*outBufHandle
= private_handle_t::dynamicCast(contents
->outbuf
);
434 /* Find normal drm layer with HWC_SKIP_LAYER */
435 /* HDCP disabled and normal DRM playback */
436 for (size_t i
= 0; i
< contents
->numHwLayers
; i
++) {
437 hwc_layer_1_t
&layer
= contents
->hwLayers
[i
];
438 if (layer
.flags
& HWC_SKIP_LAYER
) {
439 ALOGV("skipping layer %d", i
);
441 private_handle_t
*h
= private_handle_t::dynamicCast(layer
.handle
);
442 if (getDrmMode(h
->flags
) == NORMAL_DRM
&& mIsWFDState
) {
443 ALOGV("skipped normal drm layer %d", i
);
444 IsNormalDRMWithSkipLayer
= true;
451 for (size_t i
= 0; i
< contents
->numHwLayers
; i
++) {
452 hwc_layer_1_t
&layer
= contents
->hwLayers
[i
];
454 if (layer
.compositionType
== HWC_FRAMEBUFFER
) {
457 ALOGV("framebuffer layer %d", i
);
461 if (layer
.compositionType
== HWC_OVERLAY
) {
465 if (layer
.flags
& HWC_SKIP_RENDERING
) {
466 layer
.releaseFenceFd
= layer
.acquireFenceFd
;
470 if (outBufHandle
== NULL
&& layer
.acquireFenceFd
!= -1) {
471 close(layer
.acquireFenceFd
);
472 layer
.acquireFenceFd
= -1;
476 ALOGV("overlay layer %d", i
);
477 mOverlayLayer
= &layer
;
481 if (layer
.compositionType
== HWC_FRAMEBUFFER_TARGET
) {
485 ALOGV("FB target layer %d", i
);
487 mFBTargetLayer
= &layer
;
492 if (outBufHandle
== NULL
) {
493 ALOGE("set, outbuf is invalid, no overlay");
494 mOverlayLayer
= NULL
;
495 mCompositionType
= COMPOSITION_GLES
;
498 if (mFBTargetLayer
&& IsNormalDRMWithSkipLayer
) {
499 if (mFBTargetLayer
->acquireFenceFd
>= 0)
500 contents
->retireFenceFd
= mFBTargetLayer
->acquireFenceFd
;
501 if (contents
->outbufAcquireFenceFd
>= 0) {
502 close(contents
->outbufAcquireFenceFd
);
503 contents
->outbufAcquireFenceFd
= -1;
505 } else if (mFBTargetLayer
&& mCompositionType
== COMPOSITION_GLES
) {
506 processGles(contents
);
507 } else if (mFBTargetLayer
&& mOverlayLayer
&& mNumFB
> 0 && mCompositionType
== COMPOSITION_MIXED
) {
508 processMixed(contents
);
509 } else if (mOverlayLayer
) {
510 processHwc(contents
);
511 #ifdef USES_DISABLE_COMPOSITIONTYPE_GLES
512 } else if (mOverlayLayer
== NULL
&& mCompositionType
== COMPOSITION_MIXED
) {
513 ALOGV("Use Scaler to copy from SCRATCH buffer to SINK buffer");
515 buffer_handle_t tempBuffers
= mExternalMPPforCSC
->mDstBuffers
[mExternalMPPforCSC
->mCurrentBuf
];
516 int tempFence
= mExternalMPPforCSC
->mDstBufFence
[mExternalMPPforCSC
->mCurrentBuf
];
518 mExternalMPPforCSC
->mDstBuffers
[mExternalMPPforCSC
->mCurrentBuf
] = contents
->outbuf
;
519 mExternalMPPforCSC
->mDstBufFence
[mExternalMPPforCSC
->mCurrentBuf
] = contents
->outbufAcquireFenceFd
;
521 ret
= mExternalMPPforCSC
->processM2M(*mFBTargetLayer
, outBufHandle
->format
, NULL
, false);
523 ALOGE("failed to configure scaler");
524 contents
->outbufAcquireFenceFd
= -1;
525 contents
->retireFenceFd
= mExternalMPPforCSC
->mDstConfig
.releaseFenceFd
;
526 mExternalMPPforCSC
->mDstBuffers
[mExternalMPPforCSC
->mCurrentBuf
] = tempBuffers
;
527 mExternalMPPforCSC
->mDstBufFence
[mExternalMPPforCSC
->mCurrentBuf
] = tempFence
;
529 if (contents
->outbufAcquireFenceFd
>= 0) {
530 close(contents
->outbufAcquireFenceFd
);
531 contents
->outbufAcquireFenceFd
= -1;
535 ALOGV("animation layer skip");
536 if (mFBTargetLayer
&& mFBTargetLayer
->acquireFenceFd
>= 0)
537 contents
->retireFenceFd
= mFBTargetLayer
->acquireFenceFd
;
538 if (contents
->outbufAcquireFenceFd
>= 0) {
539 close(contents
->outbufAcquireFenceFd
);
540 contents
->outbufAcquireFenceFd
= -1;
544 mPrevCompositionType
= mCompositionType
;
549 #ifdef USES_VDS_OTHERFORMAT
550 bool ExynosVirtualDisplay::isSupportGLESformat()
556 void ExynosVirtualDisplay::determineSkipLayer(hwc_display_contents_1_t
*contents
)
558 /* If there is rotation animation layer, */
559 /* all layer is HWC_OVERLAY and HWC_SKIP_RENDERING */
560 for (size_t i
= 0; i
< contents
->numHwLayers
; i
++) {
561 hwc_layer_1_t
&layer
= contents
->hwLayers
[i
];
563 if (layer
.compositionType
== HWC_FRAMEBUFFER_TARGET
) {
567 if (mIsRotationState
) {
568 // normal layers can be skip layer.
570 private_handle_t
*h
= private_handle_t::dynamicCast(layer
.handle
);
571 if (getDrmMode(h
->flags
) != NO_DRM
)
574 layer
.compositionType
= HWC_OVERLAY
;
575 layer
.flags
= HWC_SKIP_RENDERING
;
579 layer
.compositionType
= HWC_FRAMEBUFFER
;
583 void ExynosVirtualDisplay::determineYuvOverlay(hwc_display_contents_1_t
*contents
)
585 ALOGV("ExynosVirtualDisplay::determineYuvOverlay");
587 mForceOverlayLayerIndex
= -1;
588 mHasDrmSurface
= false;
590 mIsRotationState
= false;
591 mIsSecureDRM
= false;
592 mIsNormalDRM
= false;
593 bool useVPPOverlayFlag
= false;
595 if (mDisplayFd
< 0) {
596 ALOGE("determineYuvOverlay, mDisplayFd is invalid , no overlay");
600 #ifdef USES_VDS_OTHERFORMAT
601 if (!isSupportGLESformat()) {
602 ALOGE("determineYuvOverlay, GLES format is not suppoted, no overlay");
607 #ifdef HWC_SCREENSHOT_ANIMATOR_LAYER
608 /* find rotation animation layer */
609 for (size_t i
= 0; i
< contents
->numHwLayers
; i
++) {
610 hwc_layer_1_t
&layer
= contents
->hwLayers
[i
];
612 if (layer
.flags
& HWC_SCREENSHOT_ANIMATOR_LAYER
) {
613 ALOGV("include rotation animation layer");
614 mIsRotationState
= true;
620 private_handle_t
*outBufHandle
= private_handle_t::dynamicCast(contents
->outbuf
);
621 if (outBufHandle
== NULL
) {
622 ALOGE("determineYuvOverlay, outbuf is invalid, no overlay");
626 for (size_t i
= 0; i
< contents
->numHwLayers
; i
++) {
627 ExynosMPPModule
* supportedInternalMPP
= NULL
;
628 ExynosMPPModule
* supportedExternalMPP
= NULL
;
629 hwc_layer_1_t
&layer
= contents
->hwLayers
[i
];
631 if (layer
.compositionType
== HWC_FRAMEBUFFER_TARGET
)
634 useVPPOverlayFlag
= false;
636 private_handle_t
*handle
= private_handle_t::dynamicCast(layer
.handle
);
638 if (getDrmMode(handle
->flags
) != NO_DRM
) {
639 useVPPOverlayFlag
= true;
640 layer
.flags
&= ~HWC_SKIP_RENDERING
;
643 /* check yuv surface */
644 if (!mForceFb
&& !isFormatRgb(handle
->format
)) {
646 /* HACK: force integer source crop */
647 layer
.sourceCropf
.top
= floor(layer
.sourceCropf
.top
);
648 layer
.sourceCropf
.left
= floor(layer
.sourceCropf
.left
);
649 layer
.sourceCropf
.bottom
= ceil(layer
.sourceCropf
.bottom
);
650 layer
.sourceCropf
.right
= ceil(layer
.sourceCropf
.right
);
652 if (isOverlaySupported(contents
->hwLayers
[i
], i
, useVPPOverlayFlag
, &supportedInternalMPP
, &supportedExternalMPP
)) {
654 if (this->mHasDrmSurface
== false) {
656 if (supportedExternalMPP
!= NULL
)
657 supportedExternalMPP
->mState
= MPP_STATE_ASSIGNED
;
658 if (supportedInternalMPP
!= NULL
)
659 supportedInternalMPP
->mState
= MPP_STATE_ASSIGNED
;
661 mForceOverlayLayerIndex
= i
;
662 layer
.compositionType
= HWC_OVERLAY
;
663 mLayerInfos
[i
]->mExternalMPP
= supportedExternalMPP
;
664 mLayerInfos
[i
]->mInternalMPP
= supportedInternalMPP
;
665 mLayerInfos
[i
]->compositionType
= layer
.compositionType
;
667 if ((getDrmMode(handle
->flags
) != NO_DRM
) &&
668 isBothMPPProcessingRequired(layer
) &&
669 (supportedInternalMPP
!= NULL
)) {
670 layer
.displayFrame
.right
= layer
.displayFrame
.left
+
671 ALIGN_DOWN(WIDTH(layer
.displayFrame
), supportedInternalMPP
->getCropWidthAlign(layer
));
672 layer
.displayFrame
.bottom
= layer
.displayFrame
.top
+
673 ALIGN_DOWN(HEIGHT(layer
.displayFrame
), supportedInternalMPP
->getCropHeightAlign(layer
));
676 if ((getDrmMode(handle
->flags
) != NO_DRM
) &&
677 (supportedInternalMPP
!= NULL
)) {
678 if (WIDTH(layer
.displayFrame
) < supportedInternalMPP
->getMinWidth(layer
)) {
679 ALOGE("determineYuvOverlay layer %d displayFrame width %d is smaller than vpp minWidth %d",
680 i
, WIDTH(layer
.displayFrame
), supportedInternalMPP
->getMinWidth(layer
));
681 layer
.displayFrame
.right
= layer
.displayFrame
.left
+
682 ALIGN_DOWN(WIDTH(layer
.displayFrame
), supportedInternalMPP
->getMinWidth(layer
));
684 if (HEIGHT(layer
.displayFrame
) < supportedInternalMPP
->getMinHeight(layer
)) {
685 ALOGE("determineYuvOverlay layer %d displayFrame height %d is smaller than vpp minHeight %d",
686 i
, HEIGHT(layer
.displayFrame
), supportedInternalMPP
->getMinHeight(layer
));
687 layer
.displayFrame
.bottom
= layer
.displayFrame
.top
+
688 ALIGN_DOWN(HEIGHT(layer
.displayFrame
), supportedInternalMPP
->getMinHeight(layer
));
692 if (getDrmMode(handle
->flags
) == SECURE_DRM
) {
694 mOverlayLayer
= &layer
;
695 calcDisplayRect(layer
);
696 ALOGV("include secure drm layer");
698 if (getDrmMode(handle
->flags
) == NORMAL_DRM
) {
700 mOverlayLayer
= &layer
;
701 calcDisplayRect(layer
);
702 ALOGV("include normal drm layer");
706 if (getDrmMode(handle
->flags
) != NO_DRM
) {
707 /* This layer should be overlay but HWC can't handle it */
708 layer
.compositionType
= HWC_OVERLAY
;
709 mLayerInfos
[i
]->compositionType
= layer
.compositionType
;
710 layer
.flags
|= HWC_SKIP_RENDERING
;
713 if (getDrmMode(handle
->flags
) != NO_DRM
) {
714 this->mHasDrmSurface
= true;
715 mForceOverlayLayerIndex
= i
;
722 void ExynosVirtualDisplay::determineSupportedOverlays(hwc_display_contents_1_t
*contents
)
724 ALOGV("ExynosVirtualDisplay::determineSupportedOverlays");
726 if (mDisplayFd
< 0) {
727 ALOGE("determineSupportedOverlays, mDisplayFd is invalid , no overlay");
731 #ifdef USES_VDS_OTHERFORMAT
732 if (!isSupportGLESformat()) {
733 ALOGE("determineSupportedOverlays, GLES format is not suppoted, no overlay");
738 if (mIsRotationState
)
741 private_handle_t
*outBufHandle
= private_handle_t::dynamicCast(contents
->outbuf
);
742 if (outBufHandle
== NULL
) {
743 ALOGE("determineSupportedOverlays, outbuf is invalid, no overlay");
747 ExynosDisplay::determineSupportedOverlays(contents
);
750 void ExynosVirtualDisplay::determineBandwidthSupport(hwc_display_contents_1_t
*contents
)
752 ALOGV("ExynosVirtualDisplay::determineBandwidthSupport");
754 if (mDisplayFd
< 0) {
755 ALOGE("determineBandwidthSupport, mDisplayFd is invalid , no overlay");
759 #ifdef USES_VDS_OTHERFORMAT
760 if (!isSupportGLESformat()) {
761 ALOGE("determineBandwidthSupport, GLES format is not suppoted, no overlay");
766 if (mIsRotationState
)
769 private_handle_t
*outBufHandle
= private_handle_t::dynamicCast(contents
->outbuf
);
770 if (outBufHandle
== NULL
) {
771 ALOGE("determineBandwidthSupport, outbuf is invalid, no overlay");
775 ExynosDisplay::determineBandwidthSupport(contents
);
778 #ifdef USES_VDS_BGRA8888
779 bool ExynosVirtualDisplay::isBothMPPProcessingRequired(hwc_layer_1_t
&layer
)
781 if (mForceDoubleOperation
)
784 return ExynosDisplay::isBothMPPProcessingRequired(layer
);
788 void ExynosVirtualDisplay::calcDisplayRect(hwc_layer_1_t
&layer
)
790 bool needToTransform
= false;
791 unsigned int newTransform
= 0;
792 unsigned int calc_w
= (mWidth
- mDisplayWidth
) >> 1;
793 unsigned int calc_h
= (mHeight
- mDisplayHeight
) >> 1;
795 if (layer
.compositionType
) {
796 if (mPresentationMode
) {
797 /* Use EXTERNAL_TB directly (DRM-extention) */
798 newTransform
= layer
.transform
;
799 needToTransform
= false;
800 } else if (mFrameBufferTargetTransform
) {
801 switch(mFrameBufferTargetTransform
) {
802 case HAL_TRANSFORM_ROT_90
:
804 needToTransform
= true;
806 case HAL_TRANSFORM_ROT_180
:
807 newTransform
= HAL_TRANSFORM_ROT_90
;
808 needToTransform
= false;
810 case HAL_TRANSFORM_ROT_270
:
811 newTransform
= HAL_TRANSFORM_ROT_180
;
812 needToTransform
= true;
816 needToTransform
= false;
820 switch(mDeviceOrientation
) {
821 case 1: /* HAL_TRANSFORM_ROT_90 */
822 newTransform
= HAL_TRANSFORM_ROT_270
;
823 needToTransform
= false;
825 case 3: /* HAL_TRANSFORM_ROT_270 */
826 newTransform
= HAL_TRANSFORM_ROT_90
;
827 needToTransform
= false;
829 default: /* Default | HAL_TRANSFORM_ROT_180 */
831 needToTransform
= false;
836 if (layer
.compositionType
== HWC_OVERLAY
) {
837 if (needToTransform
) {
838 mHwc
->mVirtualDisplayRect
.left
= layer
.displayFrame
.left
+ calc_h
;
839 mHwc
->mVirtualDisplayRect
.top
= layer
.displayFrame
.top
+ calc_w
;
840 mHwc
->mVirtualDisplayRect
.width
= WIDTH(layer
.displayFrame
) - (calc_h
<< 1);
841 mHwc
->mVirtualDisplayRect
.height
= HEIGHT(layer
.displayFrame
) - (calc_w
<< 1);
843 mHwc
->mVirtualDisplayRect
.left
= layer
.displayFrame
.left
+ calc_w
;
844 mHwc
->mVirtualDisplayRect
.top
= layer
.displayFrame
.top
+ calc_h
;
845 mHwc
->mVirtualDisplayRect
.width
= WIDTH(layer
.displayFrame
) - (calc_w
<< 1);
846 mHwc
->mVirtualDisplayRect
.height
= HEIGHT(layer
.displayFrame
) - (calc_h
<< 1);
849 if (layer
.displayFrame
.left
< 0 || layer
.displayFrame
.top
< 0 ||
850 mWidth
< (unsigned int)WIDTH(layer
.displayFrame
) || mHeight
< (unsigned int)HEIGHT(layer
.displayFrame
)) {
851 if (needToTransform
) {
852 mHwc
->mVirtualDisplayRect
.left
= 0 + calc_h
;
853 mHwc
->mVirtualDisplayRect
.top
= 0 + calc_w
;
855 mHwc
->mVirtualDisplayRect
.width
= mWidth
- (calc_h
<< 1);
856 mHwc
->mVirtualDisplayRect
.height
= mHeight
- (calc_w
<< 1);
858 mHwc
->mVirtualDisplayRect
.left
= 0 + calc_w
;
859 mHwc
->mVirtualDisplayRect
.top
= 0 + calc_h
;
861 mHwc
->mVirtualDisplayRect
.width
= mWidth
- (calc_w
<< 1);
862 mHwc
->mVirtualDisplayRect
.height
= mHeight
- (calc_h
<< 1);
865 } else { /* HWC_FRAMEBUFFER_TARGET */
866 if (needToTransform
) {
867 mHwc
->mVirtualDisplayRect
.width
= (mDisplayHeight
* mDisplayHeight
) / mDisplayWidth
;
868 mHwc
->mVirtualDisplayRect
.height
= mDisplayHeight
;
869 mHwc
->mVirtualDisplayRect
.left
= (mDisplayWidth
- mHwc
->mVirtualDisplayRect
.width
) / 2;
870 mHwc
->mVirtualDisplayRect
.top
= 0;
872 mHwc
->mVirtualDisplayRect
.left
= 0;
873 mHwc
->mVirtualDisplayRect
.top
= 0;
874 mHwc
->mVirtualDisplayRect
.width
= mDisplayWidth
;
875 mHwc
->mVirtualDisplayRect
.height
= mDisplayHeight
;
881 void ExynosVirtualDisplay::init(hwc_display_contents_1_t __unused
*contents
)
883 ALOGV("ExynosVirtualDisplay::init() mDisplayFd %d", mDisplayFd
);
885 #ifdef USES_VDS_BGRA8888
886 private_handle_t
*handle
= private_handle_t::dynamicCast(contents
->outbuf
);
888 if (handle
->format
== HAL_PIXEL_FORMAT_BGRA_8888
) {
889 mForceDoubleOperation
= false;
891 mForceDoubleOperation
= true;
894 ALOGV("ExynosVirtualDisplay::init() mForceDoubleOperation %d", mForceDoubleOperation
);
897 #ifdef USES_VIRTUAL_DISPLAY_DECON_EXT_WB
899 if (mDisplayFd
< 0) {
900 mDisplayFd
= open(DECON_WB_DEV_NAME
, O_RDWR
);
901 if (mDisplayFd
< 0) {
902 ALOGE("failed to open decon ext wb for virtualDisplay");
904 ALOGD("open fd for WFD(%d)", mDisplayFd
);
906 struct v4l2_subdev_format sd_fmt
;
909 sd_fmt
.pad
= DECON_PAD_WB
;
910 sd_fmt
.which
= V4L2_SUBDEV_FORMAT_ACTIVE
;
911 sd_fmt
.format
.width
= mWidth
;
912 sd_fmt
.format
.height
= mHeight
;
914 snprintf(devname
, sizeof(devname
), DECON_WB_SUBDEV_NAME
);
916 subdev_fd
= exynos_subdev_open_devname(devname
, O_RDWR
);
918 ALOGE("failed to open subdev for virtualDisplay");
920 ret
= exynos_subdev_s_fmt(subdev_fd
, &sd_fmt
);
923 ALOGE("failed to subdev s_fmt for virtualDisplay");
933 void ExynosVirtualDisplay::deInit()
935 ALOGV("ExynosVirtualDisplay::deInit() ,mDisplayFd %d", mDisplayFd
);
939 if (mDisplayFd
> 0) {
941 ALOGD("Close fd for WFD");
946 #ifdef USE_VIDEO_EXT_FOR_WFD_DRM
947 void ExynosVirtualDisplay::requestIONMemory()
949 ALOGV("ExynosVirtualDisplay::requestIONMemory()");
950 /* prepare reserved memory */
951 if (mReserveMemFd
> 0) {
953 int waitCount
= WAIT_COUNT_FOR_ISOLATION
;
955 memset(buffer
, 0, sizeof(buffer
));
956 int err
= lseek(mReserveMemFd
, 0, SEEK_SET
);
957 err
= read(mReserveMemFd
, buffer
, sizeof(buffer
));
958 value
= atoi(buffer
);
960 if ((err
> 0) && (value
== 0)) {
961 memset(buffer
, 0, sizeof(buffer
));
963 if (write(mReserveMemFd
, buffer
, sizeof(buffer
)) < 0)
964 ALOGE("fail to request isolation of memmory for WFD");
966 while(!checkIONBufferPrepared()) {
969 ALOGV("wait count for isolation: %d", waitCount
);
971 ALOGE("fail to request isolation (time out)");
973 ALOGI("video ext ion memory for WFD was isolated");
977 ALOGE("fail to read mReserveMemFd");
979 ALOGE("ion memmory for WFD is isolated already");
984 void ExynosVirtualDisplay::freeIONMemory()
986 ALOGV("ExynosVirtualDisplay::freeIONMemory()");
987 if (mReserveMemFd
> 0 && mFlagIONBufferAllocated
) {
990 memset(buffer
, 0, sizeof(buffer
));
991 int err
= lseek(mReserveMemFd
, 0, SEEK_SET
);
992 err
= read(mReserveMemFd
, buffer
, sizeof(buffer
));
993 value
= atoi(buffer
);
994 if ((err
> 0) && (value
== 1)) {
995 setMemoryProtection(0);
996 memset(buffer
, 0, sizeof(buffer
));
998 if (write(mReserveMemFd
, buffer
, sizeof(buffer
)) < 0)
999 ALOGE("fail to request isolation of memmory for WFD");
1001 ALOGI("deisolation of memmory for WFD was requested");
1004 ALOGE("fail to read mReserveMemFd");
1006 ALOGE("ion memmory for WFD is deisolated already");
1008 mFlagIONBufferAllocated
= false;
1012 bool ExynosVirtualDisplay::checkIONBufferPrepared()
1014 ALOGV("ExynosVirtualDisplay::checkIONBufferPrepared()");
1015 if (mReserveMemFd
> 0) {
1018 memset(buffer
, 0, sizeof(buffer
));
1019 int err
= lseek(mReserveMemFd
, 0, SEEK_SET
);
1020 err
= read(mReserveMemFd
, buffer
, sizeof(buffer
));
1021 value
= atoi(buffer
);
1023 if ((err
> 0) && (value
== 1)) {
1024 mFlagIONBufferAllocated
= true;
1027 mFlagIONBufferAllocated
= false;
1034 void ExynosVirtualDisplay::setMemoryProtection(int protection
)
1036 ALOGV("ExynosVirtualDisplay::setMemoryProtection() protection %d", protection
);
1040 ret
= ioctl(mSMemFd
, SECMEM_IOC_SET_VIDEO_EXT_PROC
, &protection
);
1042 ALOGE("Protection failed, ret(%d)", ret
);
1047 void ExynosVirtualDisplay::setWFDOutputResolution(unsigned int width
, unsigned int height
,
1048 unsigned int disp_w
, unsigned int disp_h
)
1052 mDisplayWidth
= disp_w
;
1053 mDisplayHeight
= disp_h
;
1058 #ifdef USES_VDS_OTHERFORMAT
1059 void ExynosVirtualDisplay::setVDSGlesFormat(int format
)
1061 ALOGV("ExynosVirtualDisplay::setVDSGlesFormat(), format %d", format
);
1062 mGLESFormat
= format
;
1066 void ExynosVirtualDisplay::setPriContents(hwc_display_contents_1_t __unused
*contents
)
1071 int ExynosVirtualDisplay::blank()
1073 ALOGV("ExynosVirtualDisplay::blank(), mDisplayFd %d, mBlanked %d", mDisplayFd
, mBlanked
);
1076 if (mDisplayFd
> 0 && !mBlanked
) {
1077 ret
= ioctl(mDisplayFd
, FBIOBLANK
, FB_BLANK_POWERDOWN
);
1079 ALOGE("failed blank for virtualDisplay");
1086 int ExynosVirtualDisplay::unblank()
1088 ALOGV("ExynosVirtualDisplay::unblank(), mDisplayFd %d, mBlanked %d", mDisplayFd
, mBlanked
);
1090 if (mDisplayFd
> 0 && mBlanked
) {
1091 ret
= ioctl(mDisplayFd
, FBIOBLANK
, FB_BLANK_UNBLANK
);
1093 ALOGE("failed unblank for virtualDisplay");
1100 int ExynosVirtualDisplay::getConfig()
1105 int32_t ExynosVirtualDisplay::getDisplayAttributes(const uint32_t __unused attribute
)