libhwjpeg: resolve compilation errors
[GitHub/LineageOS/android_hardware_samsung_slsi_exynos.git] / libvppvirtualdisplay / ExynosVirtualDisplay.cpp
CommitLineData
5763fb39
T
1#define ATRACE_TAG ATRACE_TAG_GRAPHICS
2
3//#define LOG_NDEBUG 0
4#define LOG_TAG "virtualdisplay"
5#include "exynos_format.h"
6#include "ExynosHWC.h"
7#include "ExynosHWCUtils.h"
8#include "ExynosMPPModule.h"
9#include "ExynosVirtualDisplay.h"
10#include "decon_tv.h"
11#ifdef USES_DISABLE_COMPOSITIONTYPE_GLES
12#include "ExynosPrimaryDisplay.h"
13#endif
14#include <errno.h>
15#include <utils/Trace.h>
16
17#ifdef USE_VIDEO_EXT_FOR_WFD_DRM
18#define WAIT_COUNT_FOR_ISOLATION 50
19#endif
20
21ExynosVirtualDisplay::ExynosVirtualDisplay(struct exynos5_hwc_composer_device_1_t *pdev) :
22 ExynosDisplay(EXYNOS_VIRTUAL_DISPLAY, pdev),
23 mWidth(0),
24 mHeight(0),
25 mDisplayWidth(0),
26 mDisplayHeight(0),
27 mIsWFDState(false),
28 mIsRotationState(false),
29 mPresentationMode(0),
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),
36 mIsSecureDRM(false),
37 mIsNormalDRM(false)
38#ifdef USE_VIDEO_EXT_FOR_WFD_DRM
39 , mSMemFd(-1),
40 mSMemProtected(false),
41 mReserveMemFd(-1),
42 mFlagIONBufferAllocated(false)
43#endif
44{
45 mXres = 0;
46 mYres = 0;
47 mXdpi = 0;
48 mYdpi = 0;
49#ifdef USES_DISABLE_COMPOSITIONTYPE_GLES
50 mExternalMPPforCSC = new ExynosMPPModule(this, MPP_MSC, 0);
51 mExternalMPPforCSC->setAllocDevice(pdev->primaryDisplay->mAllocDevice);
52#endif
53
54 mOverlayLayer = NULL;
55 mFBTargetLayer = NULL;
56 memset(mFBLayer, 0x0, sizeof(hwc_layer_1_t *) * NUM_FRAME_BUFFER);
57 mNumFB = 0;
58
59#ifdef USES_VDS_BGRA8888
60 mForceDoubleOperation = false;
61 mExternalMPPDstFormat = HAL_PIXEL_FORMAT_RGBA_8888;
62#endif
63
64#ifdef USE_VIDEO_EXT_FOR_WFD_DRM
65 mSMemFd = open(SMEM_PATH, O_RDWR);
66 if (mSMemFd < 0)
67 ALOGE("Fail to open smem_fd %s, error(%d)", SMEM_PATH, mSMemFd);
68 else
69 ALOGI("Open %s", SMEM_PATH);
70
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);
74 else
75 ALOGI("Open %s", HDMI_RESERVE_MEM_DEV_NAME);
76#endif
77}
78
79ExynosVirtualDisplay::~ExynosVirtualDisplay()
80{
81#ifdef USE_VIDEO_EXT_FOR_WFD_DRM
82 if (mSMemFd > 0)
83 close(mSMemFd);
84 if (mReserveMemFd > 0)
85 close(mReserveMemFd);
86#endif
87}
88
89void ExynosVirtualDisplay::allocateLayerInfos(hwc_display_contents_1_t* contents)
90{
91 ExynosDisplay::allocateLayerInfos(contents);
92
93}
94
95void ExynosVirtualDisplay::setSinkBufferUsage()
96{
97 ALOGV("setSinkBufferUsage() mSinkUsage 0x%x, mIsSecureDRM %d, mIsNormalDRM %d",
98 mSinkUsage, mIsSecureDRM, mIsNormalDRM);
99 mSinkUsage = GRALLOC_USAGE_HW_COMPOSER;
100
101 if (mIsSecureDRM) {
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;
111 }
112 }
113#endif
114 } else if (mIsNormalDRM)
115 mSinkUsage |= GRALLOC_USAGE_PRIVATE_NONSECURE;
116
117#ifdef USE_VIDEO_EXT_FOR_WFD_DRM
118 if (mReserveMemFd > 0 && !mIsSecureDRM && mSMemProtected) {
119 setMemoryProtection(0);
120 mSMemProtected = false;
121 }
122#endif
123
124 ALOGV("Sink Buffer's Usage: 0x%x", mSinkUsage);
125}
126
127int ExynosVirtualDisplay::prepare(hwc_display_contents_1_t* contents)
128{
129 ATRACE_CALL();
130 ALOGV("prepare %u layers for virtual, outbuf %p", contents->numHwLayers, contents->outbuf);
131
132 int ret = 0;
133 mCompositionType = COMPOSITION_GLES;
134 mOverlayLayer = NULL;
135 mFBTargetLayer = NULL;
136 mNumFB = 0;
137
138 determineSkipLayer(contents);
139
140 /* determine composition type */
141 for (size_t i = 0; i < contents->numHwLayers; i++) {
142 hwc_layer_1_t &layer = contents->hwLayers[i];
143
144 if (layer.compositionType == HWC_FRAMEBUFFER) {
145 mNumFB++;
146 if (!layer.handle)
147 continue;
148
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);
159 }
160
161 if (layer.compositionType == HWC_OVERLAY) {
162 if (!layer.handle)
163 continue;
164
165 if (layer.flags & HWC_SKIP_RENDERING) {
166 layer.releaseFenceFd = layer.acquireFenceFd;
167 continue;
168 }
169
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);
180
181 mOverlayLayer = &layer;
182 continue;
183 }
184
185 if (layer.compositionType == HWC_FRAMEBUFFER_TARGET) {
186 if (!layer.handle)
187 continue;
188
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);
199
200 mFBTargetLayer = &layer;
201 continue;
202 }
203 }
204
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);
211
212 if (mCompositionType == COMPOSITION_GLES)
213 blank();
214 else
215 unblank();
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;
223 }
224#endif
225
226#ifdef USES_VDS_BGRA8888
227 if (mCompositionType != COMPOSITION_GLES && contents->outbuf) {
228 private_handle_t *outbuf_handle = private_handle_t::dynamicCast(contents->outbuf);
229 if (outbuf_handle) {
230 mGLESFormat = outbuf_handle->format;
231 }
232 }
233#endif
234
235 setSinkBufferUsage();
236
237 return 0;
238}
239
240void ExynosVirtualDisplay::configureHandle(private_handle_t *handle, size_t index,
241 hwc_layer_1_t &layer, int fence_fd, decon_win_config &cfg)
242{
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);
247#endif
248}
249
250void ExynosVirtualDisplay::configureWriteBack(hwc_display_contents_1_t __unused *contents,
251 decon_win_config_data __unused &win_data)
252{
253}
254
255int ExynosVirtualDisplay::postFrame(hwc_display_contents_1_t* contents)
256{
257#ifdef USES_VIRTUAL_DISPLAY_DECON_EXT_WB
258 ATRACE_CALL();
259 struct decon_win_config_data win_data;
260 struct decon_win_config *config = win_data.config;
261 int win_map = 0;
262 int tot_ovly_wins = 0;
263 bool hasSecureLayer = false;
264
265 memset(mLastHandles, 0, sizeof(mLastHandles));
266 memset(mLastMPPMap, 0, sizeof(mLastMPPMap));
267 memset(config, 0, sizeof(win_data.config));
268
269 if (contents->outbuf) {
270 configureWriteBack(contents, win_data);
271 }
272
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;
277 }
278
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;
285
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;
293
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());
299 result.clear();
300 dumpLayerInfo(result);
301 ALOGW(result.string());
302 }
303
304 continue;
305 }
306
307 if ((layer.compositionType == HWC_OVERLAY) ||
308 (mFbNeeded == true && layer.compositionType == HWC_FRAMEBUFFER_TARGET)) {
309 mLastHandles[window_index] = layer.handle;
310
311 if ((getDrmMode(handle->flags) == SECURE_DRM) && layer.compositionType != HWC_FRAMEBUFFER_TARGET) {
312 config[window_index].protection = 1;
313 hasSecureLayer = true;
314 }
315 else
316 config[window_index].protection = 0;
317
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;
321 }
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)
326 continue;
327 } else {
328 configureOverlay(&layer, i, config[window_index]);
329 }
330 }
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;
334 }
335 }
336
337 for (size_t i = 0; i < NUM_HW_WINDOWS; i++) {
338 ALOGV("window %u configuration:", i);
339 dumpConfig(config[i]);
340 }
341
342 /* This should be enabled */
343#if 0
344 if (this->mVirtualOverlayFlag) {
345 handleStaticLayers(contents, win_data, tot_ovly_wins);
346 }
347#endif
348
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);
352 if (outbuf_handle)
353 ALOGW("outbuf format: 0x%x, mCompositionType: %d", outbuf_handle->format, mCompositionType);
354 }
355
356 int ret = winconfigIoctl(&win_data);
357 ALOGV("ExynosDisplay::postFrame() ioctl(S3CFB_WIN_CONFIG) ret %d", ret);
358
359 for (size_t i = 0; i < NUM_HW_WINDOWS; i++)
360 if (config[i].fence_fd != -1)
361 close(config[i].fence_fd);
362 if (ret < 0) {
363 ALOGE("ioctl S3CFB_WIN_CONFIG failed: %s", strerror(errno));
364 return ret;
365 }
366 if (contents->numHwLayers == 1) {
367 hwc_layer_1_t &layer = contents->hwLayers[0];
368 if (layer.acquireFenceFd >= 0)
369 close(layer.acquireFenceFd);
370 }
371
372 memcpy(&(this->mLastConfigData), &win_data, sizeof(win_data));
373
374 if (!this->mVirtualOverlayFlag)
375 this->mLastFbWindow = mFbWindow;
376
377 return win_data.fence;
378#else
379 return 0;
380#endif
381}
382
383void ExynosVirtualDisplay::processGles(hwc_display_contents_1_t* contents)
384{
385 ALOGV("processGles, mFBTargetLayer->acquireFenceFd %d, mFBTargetLayer->releaseFenceFd %d, contents->outbufAcquireFenceFd %d",
386 mFBTargetLayer->acquireFenceFd, mFBTargetLayer->releaseFenceFd, contents->outbufAcquireFenceFd);
387 int ret = 0;
388 if (mFBTargetLayer != NULL && mFBTargetLayer->acquireFenceFd >= 0)
389 contents->retireFenceFd = mFBTargetLayer->acquireFenceFd;
390
391 if (contents->outbufAcquireFenceFd >= 0) {
392 close(contents->outbufAcquireFenceFd);
393 contents->outbufAcquireFenceFd = -1;
394 }
395}
396
397void ExynosVirtualDisplay::processHwc(hwc_display_contents_1_t* contents)
398{
399 ALOGV("processHwc, mFBTargetLayer->acquireFenceFd %d, mFBTargetLayer->releaseFenceFd %d, contents->outbufAcquireFenceFd %d",
400 mFBTargetLayer->acquireFenceFd, mFBTargetLayer->releaseFenceFd, contents->outbufAcquireFenceFd);
401
402 ExynosDisplay::set(contents);
403
404 if (contents->outbufAcquireFenceFd >= 0) {
405 close(contents->outbufAcquireFenceFd);
406 contents->outbufAcquireFenceFd = -1;
407 }
408}
409
410void ExynosVirtualDisplay::processMixed(hwc_display_contents_1_t* contents)
411{
412 ALOGV("processMixed, mFBTargetLayer->acquireFenceFd %d, mFBTargetLayer->releaseFenceFd %d, contents->outbufAcquireFenceFd %d",
413 mFBTargetLayer->acquireFenceFd, mFBTargetLayer->releaseFenceFd, contents->outbufAcquireFenceFd);
414
415 ExynosDisplay::set(contents);
416
417 if (contents->outbufAcquireFenceFd >= 0) {
418 close(contents->outbufAcquireFenceFd);
419 contents->outbufAcquireFenceFd = -1;
420 }
421}
422
423int ExynosVirtualDisplay::set(hwc_display_contents_1_t* contents)
424{
425 ALOGV("set %u layers for virtual, mCompositionType %d, contents->outbuf %p",
426 contents->numHwLayers, mCompositionType, contents->outbuf);
427 mOverlayLayer = NULL;
428 mFBTargetLayer = NULL;
429 mNumFB = 0;
430 int IsNormalDRMWithSkipLayer = false;
431 int err = 0;
432 private_handle_t *outBufHandle = private_handle_t::dynamicCast(contents->outbuf);
433
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);
440 if (layer.handle) {
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;
445 }
446 }
447 continue;
448 }
449 }
450
451 for (size_t i = 0; i < contents->numHwLayers; i++) {
452 hwc_layer_1_t &layer = contents->hwLayers[i];
453
454 if (layer.compositionType == HWC_FRAMEBUFFER) {
455 if (!layer.handle)
456 continue;
457 ALOGV("framebuffer layer %d", i);
458 mNumFB++;
459 }
460
461 if (layer.compositionType == HWC_OVERLAY) {
462 if (!layer.handle)
463 continue;
464
465 if (layer.flags & HWC_SKIP_RENDERING) {
466 layer.releaseFenceFd = layer.acquireFenceFd;
467 continue;
468 }
469
470 if (outBufHandle == NULL && layer.acquireFenceFd != -1) {
471 close(layer.acquireFenceFd);
472 layer.acquireFenceFd = -1;
473 continue;
474 }
475
476 ALOGV("overlay layer %d", i);
477 mOverlayLayer = &layer;
478 continue;
479 }
480
481 if (layer.compositionType == HWC_FRAMEBUFFER_TARGET) {
482 if (!layer.handle)
483 continue;
484
485 ALOGV("FB target layer %d", i);
486
487 mFBTargetLayer = &layer;
488 continue;
489 }
490 }
491
492 if (outBufHandle == NULL) {
493 ALOGE("set, outbuf is invalid, no overlay");
494 mOverlayLayer = NULL;
495 mCompositionType = COMPOSITION_GLES;
496 }
497
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;
504 }
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");
514 int ret = 0;
515 buffer_handle_t tempBuffers = mExternalMPPforCSC->mDstBuffers[mExternalMPPforCSC->mCurrentBuf];
516 int tempFence = mExternalMPPforCSC->mDstBufFence[mExternalMPPforCSC->mCurrentBuf];
517
518 mExternalMPPforCSC->mDstBuffers[mExternalMPPforCSC->mCurrentBuf] = contents->outbuf;
519 mExternalMPPforCSC->mDstBufFence[mExternalMPPforCSC->mCurrentBuf] = contents->outbufAcquireFenceFd;
520
521 ret = mExternalMPPforCSC->processM2M(*mFBTargetLayer, outBufHandle->format, NULL, false);
522 if (ret < 0)
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;
528
529 if (contents->outbufAcquireFenceFd >= 0) {
530 close(contents->outbufAcquireFenceFd);
531 contents->outbufAcquireFenceFd = -1;
532 }
533#endif
534 } else {
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;
541 }
542 }
543
544 mPrevCompositionType = mCompositionType;
545
546 return err;
547}
548
549#ifdef USES_VDS_OTHERFORMAT
550bool ExynosVirtualDisplay::isSupportGLESformat()
551{
552 return false;
553}
554#endif
555
556void ExynosVirtualDisplay::determineSkipLayer(hwc_display_contents_1_t *contents)
557{
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];
562
563 if (layer.compositionType == HWC_FRAMEBUFFER_TARGET) {
564 continue;
565 }
566
567 if (mIsRotationState) {
568 // normal layers can be skip layer.
569 if (layer.handle) {
570 private_handle_t *h = private_handle_t::dynamicCast(layer.handle);
571 if (getDrmMode(h->flags) != NO_DRM)
572 continue;
573 }
574 layer.compositionType = HWC_OVERLAY;
575 layer.flags = HWC_SKIP_RENDERING;
576 }
577
578 if (!layer.handle)
579 layer.compositionType = HWC_FRAMEBUFFER;
580 }
581}
582
583void ExynosVirtualDisplay::determineYuvOverlay(hwc_display_contents_1_t *contents)
584{
585 ALOGV("ExynosVirtualDisplay::determineYuvOverlay");
586
587 mForceOverlayLayerIndex = -1;
588 mHasDrmSurface = false;
589 mYuvLayers = 0;
590 mIsRotationState = false;
591 mIsSecureDRM = false;
592 mIsNormalDRM = false;
593 bool useVPPOverlayFlag = false;
594
595 if (mDisplayFd < 0) {
596 ALOGE("determineYuvOverlay, mDisplayFd is invalid , no overlay");
597 return;
598 }
599
600#ifdef USES_VDS_OTHERFORMAT
601 if (!isSupportGLESformat()) {
602 ALOGE("determineYuvOverlay, GLES format is not suppoted, no overlay");
603 return;
604 }
605#endif
606
1595d47a 607#ifdef HWC_SCREENSHOT_ANIMATOR_LAYER
5763fb39
T
608 /* find rotation animation layer */
609 for (size_t i = 0; i < contents->numHwLayers; i++) {
610 hwc_layer_1_t &layer = contents->hwLayers[i];
611
612 if (layer.flags & HWC_SCREENSHOT_ANIMATOR_LAYER) {
613 ALOGV("include rotation animation layer");
614 mIsRotationState = true;
615 return;
616 }
617 }
1595d47a 618#endif
5763fb39
T
619
620 private_handle_t *outBufHandle = private_handle_t::dynamicCast(contents->outbuf);
621 if (outBufHandle == NULL) {
622 ALOGE("determineYuvOverlay, outbuf is invalid, no overlay");
623 return;
624 }
625
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];
630
631 if (layer.compositionType == HWC_FRAMEBUFFER_TARGET)
632 continue;
633
634 useVPPOverlayFlag = false;
635 if (layer.handle) {
636 private_handle_t *handle = private_handle_t::dynamicCast(layer.handle);
637
638 if (getDrmMode(handle->flags) != NO_DRM) {
639 useVPPOverlayFlag = true;
640 layer.flags &= ~HWC_SKIP_RENDERING;
641 }
642
643 /* check yuv surface */
644 if (!mForceFb && !isFormatRgb(handle->format)) {
645
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);
651
652 if (isOverlaySupported(contents->hwLayers[i], i, useVPPOverlayFlag, &supportedInternalMPP, &supportedExternalMPP)) {
653 this->mYuvLayers++;
654 if (this->mHasDrmSurface == false) {
655 /* Assign MPP */
656 if (supportedExternalMPP != NULL)
657 supportedExternalMPP->mState = MPP_STATE_ASSIGNED;
658 if (supportedInternalMPP != NULL)
659 supportedInternalMPP->mState = MPP_STATE_ASSIGNED;
660
661 mForceOverlayLayerIndex = i;
662 layer.compositionType = HWC_OVERLAY;
663 mLayerInfos[i]->mExternalMPP = supportedExternalMPP;
664 mLayerInfos[i]->mInternalMPP = supportedInternalMPP;
665 mLayerInfos[i]->compositionType = layer.compositionType;
666
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));
674 }
675
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));
683 }
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));
689 }
690 }
691
692 if (getDrmMode(handle->flags) == SECURE_DRM) {
693 mIsSecureDRM = true;
694 mOverlayLayer = &layer;
695 calcDisplayRect(layer);
696 ALOGV("include secure drm layer");
697 }
698 if (getDrmMode(handle->flags) == NORMAL_DRM) {
699 mIsNormalDRM = true;
700 mOverlayLayer = &layer;
701 calcDisplayRect(layer);
702 ALOGV("include normal drm layer");
703 }
704 }
705 } else {
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;
711 }
712 }
713 if (getDrmMode(handle->flags) != NO_DRM) {
714 this->mHasDrmSurface = true;
715 mForceOverlayLayerIndex = i;
716 }
717 }
718 }
719 }
720}
721
722void ExynosVirtualDisplay::determineSupportedOverlays(hwc_display_contents_1_t *contents)
723{
724 ALOGV("ExynosVirtualDisplay::determineSupportedOverlays");
725
726 if (mDisplayFd < 0) {
727 ALOGE("determineSupportedOverlays, mDisplayFd is invalid , no overlay");
728 return;
729 }
730
731#ifdef USES_VDS_OTHERFORMAT
732 if (!isSupportGLESformat()) {
733 ALOGE("determineSupportedOverlays, GLES format is not suppoted, no overlay");
734 return;
735 }
736#endif
737
738 if (mIsRotationState)
739 return;
740
741 private_handle_t *outBufHandle = private_handle_t::dynamicCast(contents->outbuf);
742 if (outBufHandle == NULL) {
743 ALOGE("determineSupportedOverlays, outbuf is invalid, no overlay");
744 return;
745 }
746
747 ExynosDisplay::determineSupportedOverlays(contents);
748}
749
750void ExynosVirtualDisplay::determineBandwidthSupport(hwc_display_contents_1_t *contents)
751{
752 ALOGV("ExynosVirtualDisplay::determineBandwidthSupport");
753
754 if (mDisplayFd < 0) {
755 ALOGE("determineBandwidthSupport, mDisplayFd is invalid , no overlay");
756 return;
757 }
758
759#ifdef USES_VDS_OTHERFORMAT
760 if (!isSupportGLESformat()) {
761 ALOGE("determineBandwidthSupport, GLES format is not suppoted, no overlay");
762 return;
763 }
764#endif
765
766 if (mIsRotationState)
767 return;
768
769 private_handle_t *outBufHandle = private_handle_t::dynamicCast(contents->outbuf);
770 if (outBufHandle == NULL) {
771 ALOGE("determineBandwidthSupport, outbuf is invalid, no overlay");
772 return;
773 }
774
775 ExynosDisplay::determineBandwidthSupport(contents);
776}
777
778#ifdef USES_VDS_BGRA8888
779bool ExynosVirtualDisplay::isBothMPPProcessingRequired(hwc_layer_1_t &layer)
780{
781 if (mForceDoubleOperation)
782 return true;
783 else
784 return ExynosDisplay::isBothMPPProcessingRequired(layer);
785}
786#endif
787
788void ExynosVirtualDisplay::calcDisplayRect(hwc_layer_1_t &layer)
789{
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;
794
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:
803 newTransform = 0;
804 needToTransform = true;
805 break;
806 case HAL_TRANSFORM_ROT_180:
807 newTransform = HAL_TRANSFORM_ROT_90;
808 needToTransform = false;
809 break;
810 case HAL_TRANSFORM_ROT_270:
811 newTransform = HAL_TRANSFORM_ROT_180;
812 needToTransform = true;
813 break;
814 default:
815 newTransform = 0;
816 needToTransform = false;
817 break;
818 }
819 } else {
820 switch(mDeviceOrientation) {
821 case 1: /* HAL_TRANSFORM_ROT_90 */
822 newTransform = HAL_TRANSFORM_ROT_270;
823 needToTransform = false;
824 break;
825 case 3: /* HAL_TRANSFORM_ROT_270 */
826 newTransform = HAL_TRANSFORM_ROT_90;
827 needToTransform = false;
828 break;
829 default: /* Default | HAL_TRANSFORM_ROT_180 */
830 newTransform = 0;
831 needToTransform = false;
832 break;
833 }
834 }
835
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);
842 } else {
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);
847 }
848
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;
854
855 mHwc->mVirtualDisplayRect.width = mWidth - (calc_h << 1);
856 mHwc->mVirtualDisplayRect.height = mHeight - (calc_w << 1);
857 } else {
858 mHwc->mVirtualDisplayRect.left = 0 + calc_w;
859 mHwc->mVirtualDisplayRect.top = 0 + calc_h;
860
861 mHwc->mVirtualDisplayRect.width = mWidth - (calc_w << 1);
862 mHwc->mVirtualDisplayRect.height = mHeight - (calc_h << 1);
863 }
864 }
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;
871 } else {
872 mHwc->mVirtualDisplayRect.left = 0;
873 mHwc->mVirtualDisplayRect.top = 0;
874 mHwc->mVirtualDisplayRect.width = mDisplayWidth;
875 mHwc->mVirtualDisplayRect.height = mDisplayHeight;
876 }
877 }
878 }
879}
880
881void ExynosVirtualDisplay::init(hwc_display_contents_1_t __unused *contents)
882{
883 ALOGV("ExynosVirtualDisplay::init() mDisplayFd %d", mDisplayFd);
884
885#ifdef USES_VDS_BGRA8888
886 private_handle_t *handle = private_handle_t::dynamicCast(contents->outbuf);
887 if (handle) {
888 if (handle->format == HAL_PIXEL_FORMAT_BGRA_8888) {
889 mForceDoubleOperation = false;
890 } else {
891 mForceDoubleOperation = true;
892 }
893 }
894 ALOGV("ExynosVirtualDisplay::init() mForceDoubleOperation %d", mForceDoubleOperation);
895#endif
896
897#ifdef USES_VIRTUAL_DISPLAY_DECON_EXT_WB
898 int ret = 0;
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");
903 } else {
904 ALOGD("open fd for WFD(%d)", mDisplayFd);
905 int subdev_fd;
906 struct v4l2_subdev_format sd_fmt;
907 char devname[32];
908
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;
913
914 snprintf(devname, sizeof(devname), DECON_WB_SUBDEV_NAME);
915
916 subdev_fd = exynos_subdev_open_devname(devname, O_RDWR);
917 if (subdev_fd < 0)
918 ALOGE("failed to open subdev for virtualDisplay");
919 else {
920 ret = exynos_subdev_s_fmt(subdev_fd, &sd_fmt);
921 close(subdev_fd);
922 if (ret < 0) {
923 ALOGE("failed to subdev s_fmt for virtualDisplay");
924 close(mDisplayFd);
925 mDisplayFd = -1;
926 }
927 }
928 }
929 }
930#endif
931}
932
933void ExynosVirtualDisplay::deInit()
934{
935 ALOGV("ExynosVirtualDisplay::deInit() ,mDisplayFd %d", mDisplayFd);
936
937 blank();
938
939 if (mDisplayFd > 0) {
940 close(mDisplayFd);
941 ALOGD("Close fd for WFD");
942 }
943 mDisplayFd = -1;
944}
945
946#ifdef USE_VIDEO_EXT_FOR_WFD_DRM
947void ExynosVirtualDisplay::requestIONMemory()
948{
949 ALOGV("ExynosVirtualDisplay::requestIONMemory()");
950 /* prepare reserved memory */
951 if (mReserveMemFd > 0) {
952 unsigned int value;
953 int waitCount = WAIT_COUNT_FOR_ISOLATION;
954 char buffer[4096];
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);
959
960 if ((err > 0) && (value == 0)) {
961 memset(buffer, 0, sizeof(buffer));
962 buffer[0] = '2';
963 if (write(mReserveMemFd, buffer, sizeof(buffer)) < 0)
964 ALOGE("fail to request isolation of memmory for WFD");
965 else {
966 while(!checkIONBufferPrepared()) {
967 usleep(20000);
968 if (--waitCount)
969 ALOGV("wait count for isolation: %d", waitCount);
970 else
971 ALOGE("fail to request isolation (time out)");
972 }
973 ALOGI("video ext ion memory for WFD was isolated");
974 }
975 } else {
976 if (err < 0)
977 ALOGE("fail to read mReserveMemFd");
978 else
979 ALOGE("ion memmory for WFD is isolated already");
980 }
981 }
982}
983
984void ExynosVirtualDisplay::freeIONMemory()
985{
986 ALOGV("ExynosVirtualDisplay::freeIONMemory()");
987 if (mReserveMemFd > 0 && mFlagIONBufferAllocated) {
988 unsigned int value;
989 char buffer[4096];
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));
997 buffer[0] = '0';
998 if (write(mReserveMemFd, buffer, sizeof(buffer)) < 0)
999 ALOGE("fail to request isolation of memmory for WFD");
1000 else
1001 ALOGI("deisolation of memmory for WFD was requested");
1002 } else {
1003 if (err < 0)
1004 ALOGE("fail to read mReserveMemFd");
1005 else
1006 ALOGE("ion memmory for WFD is deisolated already");
1007 }
1008 mFlagIONBufferAllocated = false;
1009 }
1010}
1011
1012bool ExynosVirtualDisplay::checkIONBufferPrepared()
1013{
1014 ALOGV("ExynosVirtualDisplay::checkIONBufferPrepared()");
1015 if (mReserveMemFd > 0) {
1016 unsigned int value;
1017 char buffer[4096];
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);
1022
1023 if ((err > 0) && (value == 1)) {
1024 mFlagIONBufferAllocated = true;
1025 return true;
1026 } else {
1027 mFlagIONBufferAllocated = false;
1028 return false;
1029 }
1030 }
1031 return false;
1032}
1033
1034void ExynosVirtualDisplay::setMemoryProtection(int protection)
1035{
1036 ALOGV("ExynosVirtualDisplay::setMemoryProtection() protection %d", protection);
1037 int ret = 0;
1038
1039 if (mSMemFd > 0) {
1040 ret = ioctl(mSMemFd, SECMEM_IOC_SET_VIDEO_EXT_PROC, &protection);
1041 if (ret < 0)
1042 ALOGE("Protection failed, ret(%d)", ret);
1043 }
1044}
1045#endif
1046
1047void ExynosVirtualDisplay::setWFDOutputResolution(unsigned int width, unsigned int height,
1048 unsigned int disp_w, unsigned int disp_h)
1049{
1050 mWidth = width;
1051 mHeight = height;
1052 mDisplayWidth = disp_w;
1053 mDisplayHeight = disp_h;
1054 mXres = width;
1055 mYres = height;
1056}
1057
1058#ifdef USES_VDS_OTHERFORMAT
1059void ExynosVirtualDisplay::setVDSGlesFormat(int format)
1060{
1061 ALOGV("ExynosVirtualDisplay::setVDSGlesFormat(), format %d", format);
1062 mGLESFormat = format;
1063}
1064#endif
1065
1066void ExynosVirtualDisplay::setPriContents(hwc_display_contents_1_t __unused *contents)
1067{
1068
1069}
1070
1071int ExynosVirtualDisplay::blank()
1072{
1073 ALOGV("ExynosVirtualDisplay::blank(), mDisplayFd %d, mBlanked %d", mDisplayFd, mBlanked);
1074 int ret = 0;
1075
1076 if (mDisplayFd > 0 && !mBlanked) {
1077 ret = ioctl(mDisplayFd, FBIOBLANK, FB_BLANK_POWERDOWN);
1078 if (ret < 0)
1079 ALOGE("failed blank for virtualDisplay");
1080 else
1081 mBlanked = true;
1082 }
1083 return ret;
1084}
1085
1086int ExynosVirtualDisplay::unblank()
1087{
1088 ALOGV("ExynosVirtualDisplay::unblank(), mDisplayFd %d, mBlanked %d", mDisplayFd, mBlanked);
1089 int ret = 0;
1090 if (mDisplayFd > 0 && mBlanked) {
1091 ret = ioctl(mDisplayFd, FBIOBLANK, FB_BLANK_UNBLANK);
1092 if (ret < 0)
1093 ALOGE("failed unblank for virtualDisplay");
1094 else
1095 mBlanked = false;
1096 }
1097 return ret;
1098}
1099
1100int ExynosVirtualDisplay::getConfig()
1101{
1102 return 0;
1103}
1104
1105int32_t ExynosVirtualDisplay::getDisplayAttributes(const uint32_t __unused attribute)
1106{
1107 return 0;
1108}
1109