1 /*
2 * Copyright (C) 2012 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17 #include <utils/Errors.h>
18 #include <linux/videodev2.h>
19 #include <sys/mman.h>
20 #include <hardware/hwcomposer_defs.h>
21 #include <hardware/exynos/ion.h>
22 #include "ExynosLayer.h"
23 #include "ExynosResourceManager.h"
24 #include "ExynosHWCDebug.h"
25 #include "ExynosExternalDisplay.h"
26
27 #include "VendorVideoAPI.h"
28
29 /**
30 * ExynosLayer implementation
31 */
32
ExynosLayer(ExynosDisplay * display)33 ExynosLayer::ExynosLayer(ExynosDisplay* display)
34 : ExynosMPPSource(MPP_SOURCE_LAYER, this),
35 mDisplay(display),
36 mCompositionType(HWC2_COMPOSITION_INVALID),
37 mExynosCompositionType(HWC2_COMPOSITION_INVALID),
38 mValidateCompositionType(HWC2_COMPOSITION_INVALID),
39 mValidateExynosCompositionType(HWC2_COMPOSITION_INVALID),
40 mOverlayInfo(0x0),
41 mSupportedMPPFlag(0x0),
42 mFps(0),
43 mOverlayPriority(ePriorityLow),
44 mGeometryChanged(0x0),
45 mWindowIndex(0),
46 mCompressed(false),
47 mAcquireFence(-1),
48 mPrevAcquireFence(-1),
49 mReleaseFence(-1),
50 mFrameCount(0),
51 mLastFrameCount(0),
52 mLastFpsTime(0),
53 mLastLayerBuffer(NULL),
54 mLayerBuffer(NULL),
55 mDamageNum(0),
56 mBlending(HWC2_BLEND_MODE_NONE),
57 mPlaneAlpha(1.0),
58 mTransform(0),
59 mZOrder(0),
60 mDataSpace(HAL_DATASPACE_UNKNOWN),
61 mLayerFlag(0x0),
62 mIsHdrLayer(false),
63 mBufferHasMetaParcel(false),
64 mMetaParcelFd(-1) {
65 memset(&mDisplayFrame, 0, sizeof(mDisplayFrame));
66 memset(&mSourceCrop, 0, sizeof(mSourceCrop));
67 mVisibleRegionScreen.numRects = 0;
68 mVisibleRegionScreen.rects = NULL;
69 memset(&mColor, 0, sizeof(mColor));
70 memset(&mPreprocessedInfo, 0, sizeof(mPreprocessedInfo));
71 mCheckMPPFlag.clear();
72 mCheckMPPFlag.reserve(MPP_LOGICAL_TYPE_NUM);
73 mMetaParcel = NULL;
74 mDamageRects.clear();
75 }
76
~ExynosLayer()77 ExynosLayer::~ExynosLayer() {
78 if (mMetaParcel != NULL) {
79 munmap(mMetaParcel, sizeof(ExynosVideoMeta));
80 mMetaParcel = NULL;
81 }
82
83 if (mMetaParcelFd >= 0) {
84 close(mMetaParcelFd);
85 mMetaParcelFd = -1;
86 }
87
88 if (mPrevAcquireFence != -1)
89 mPrevAcquireFence = fence_close(mPrevAcquireFence, mDisplay, FENCE_TYPE_SRC_ACQUIRE,
90 FENCE_IP_UNDEFINED);
91 }
92
93 /**
94 * @return uint32_t
95 */
checkFps()96 uint32_t ExynosLayer::checkFps() {
97 uint32_t frameDiff;
98 bool wasLowFps = (mFps < LOW_FPS_THRESHOLD) ? true:false;
99 if (mLastLayerBuffer != mLayerBuffer) {
100 mFrameCount++;
101 }
102 nsecs_t now = systemTime();
103 nsecs_t diff = now - mLastFpsTime;
104 if (mFrameCount >= mLastFrameCount)
105 frameDiff = (mFrameCount - mLastFrameCount);
106 else
107 frameDiff = (mFrameCount + (UINT_MAX - mLastFrameCount));
108
109 if (diff >= ms2ns(250)) {
110 mFps = (uint32_t)(frameDiff * float(s2ns(1))) / diff;
111 mLastFrameCount = mFrameCount;
112 mLastFpsTime = now;
113 }
114 bool nowLowFps = (mFps < LOW_FPS_THRESHOLD) ? true:false;
115
116 if ((mDisplay->mDisplayControl.handleLowFpsLayers) &&
117 (wasLowFps != nowLowFps))
118 setGeometryChanged(GEOMETRY_LAYER_FPS_CHANGED);
119
120 return mFps;
121 }
122
123 /**
124 * @return float
125 */
getFps()126 uint32_t ExynosLayer::getFps() {
127 return mFps;
128 }
129
doPreProcess()130 int32_t ExynosLayer::doPreProcess()
131 {
132 overlay_priority priority = ePriorityLow;
133 mIsHdrLayer = false;
134 mBufferHasMetaParcel = false;
135 mLayerFlag = 0x0;
136
137 mPreprocessedInfo.preProcessed = false;
138 mPreprocessedInfo.sourceCrop = mSourceCrop;
139 mPreprocessedInfo.displayFrame = mDisplayFrame;
140 mPreprocessedInfo.interlacedType = V4L2_FIELD_NONE;
141
142 if (mCompositionType == HWC2_COMPOSITION_SOLID_COLOR) {
143 mLayerFlag |= EXYNOS_HWC_DIM_LAYER;
144 } else {
145 mLayerFlag &= ~(EXYNOS_HWC_DIM_LAYER);
146 }
147
148 if (mLayerBuffer == NULL) {
149 if (mOverlayPriority != priority)
150 setGeometryChanged(GEOMETRY_LAYER_PRIORITY_CHANGED);
151
152 mOverlayPriority = priority;
153 return NO_ERROR;
154 }
155
156 VendorGraphicBufferMeta gmeta(mLayerBuffer);
157
158 mPreprocessedInfo.mUsePrivateFormat = false;
159 mPreprocessedInfo.mPrivateFormat = gmeta.format;
160
161 if (isFormatYUV(gmeta.format)) {
162 mPreprocessedInfo.sourceCrop.top = (int)mSourceCrop.top;
163 mPreprocessedInfo.sourceCrop.left = (int)mSourceCrop.left;
164 mPreprocessedInfo.sourceCrop.bottom = (int)(mSourceCrop.bottom + 0.9);
165 mPreprocessedInfo.sourceCrop.right = (int)(mSourceCrop.right + 0.9);
166 mPreprocessedInfo.preProcessed = true;
167 }
168
169 if (isFormatYUV(gmeta.format)) {
170
171 ExynosVideoMeta *metaData = NULL;
172 int priv_fd = -1;
173
174 if (gmeta.flags & VendorGraphicBufferMeta::PRIV_FLAGS_USES_2PRIVATE_DATA)
175 priv_fd = gmeta.fd1;
176 else if (gmeta.flags & VendorGraphicBufferMeta::PRIV_FLAGS_USES_3PRIVATE_DATA)
177 priv_fd = gmeta.fd2;
178
179 if (priv_fd >= 0) {
180
181 metaData = (ExynosVideoMeta*)mmap(0, sizeof(ExynosVideoMeta), PROT_READ|PROT_WRITE, MAP_SHARED, priv_fd, 0);
182
183 if (metaData == NULL) {
184 HWC_LOGE(mDisplay, "Layer's metadata is NULL!!");
185 } else if (metaData == MAP_FAILED) {
186 HWC_LOGE(mDisplay, "Layer's metadata map failed!!");
187 } else {
188 mBufferHasMetaParcel = true;
189 if ((metaData->eType & VIDEO_INFO_TYPE_HDR_STATIC) ||
190 (metaData->eType & VIDEO_INFO_TYPE_HDR_DYNAMIC)) {
191 if (allocMetaParcel() == NO_ERROR) {
192 mMetaParcel->eType = metaData->eType;
193 if (metaData->eType & VIDEO_INFO_TYPE_HDR_STATIC) {
194 mMetaParcel->sHdrStaticInfo = metaData->sHdrStaticInfo;
195 HDEBUGLOGD(eDebugLayer, "HWC2: Static metadata min(%d), max(%d)",
196 mMetaParcel->sHdrStaticInfo.sType1.mMinDisplayLuminance,
197 mMetaParcel->sHdrStaticInfo.sType1.mMaxDisplayLuminance);
198 }
199 if (metaData->eType & VIDEO_INFO_TYPE_HDR_DYNAMIC) {
200 /* Reserved field for dynamic meta data */
201 /* Currently It's not be used not only HWC but also OMX */
202 mMetaParcel->sHdrDynamicInfo = metaData->sHdrDynamicInfo;
203 HDEBUGLOGD(eDebugLayer, "HWC2: Layer has dynamic metadata");
204 }
205 }
206 }
207 if (metaData->eType & VIDEO_INFO_TYPE_INTERLACED) {
208 mPreprocessedInfo.interlacedType = metaData->data.dec.nInterlacedType;
209 if (mPreprocessedInfo.interlacedType == V4L2_FIELD_INTERLACED_BT) {
210 if ((int)mSourceCrop.left < (int)(gmeta.stride)) {
211 mPreprocessedInfo.sourceCrop.left = (int)mSourceCrop.left + gmeta.stride;
212 mPreprocessedInfo.sourceCrop.right = (int)mSourceCrop.right + gmeta.stride;
213 }
214 }
215 if (mPreprocessedInfo.interlacedType == V4L2_FIELD_INTERLACED_TB ||
216 mPreprocessedInfo.interlacedType == V4L2_FIELD_INTERLACED_BT) {
217 mPreprocessedInfo.sourceCrop.top = (int)(mSourceCrop.top)/2;
218 mPreprocessedInfo.sourceCrop.bottom = (int)(mSourceCrop.bottom)/2;
219 }
220 }
221 if (metaData->eType & VIDEO_INFO_TYPE_CHECK_PIXEL_FORMAT) {
222 mPreprocessedInfo.mUsePrivateFormat = true;
223 mPreprocessedInfo.mPrivateFormat = metaData->nPixelFormat;
224 }
225 munmap(metaData, sizeof(ExynosVideoMeta));
226 }
227 }
228 mPreprocessedInfo.preProcessed = true;
229 }
230
231 exynos_image src_img;
232 exynos_image dst_img;
233 setSrcExynosImage(&src_img);
234 setDstExynosImage(&dst_img);
235 ExynosMPP *exynosMPPVG = nullptr;
236 if (isFormatYUV(gmeta.format)) {
237 auto otfMPPs = ExynosResourceManager::getOtfMPPs();
238 auto mpp_it = std::find_if(otfMPPs.begin(), otfMPPs.end(),
239 [&src_img](auto m) { return m->isSrcFormatSupported(src_img); });
240 exynosMPPVG = mpp_it == otfMPPs.end() ? nullptr : *mpp_it;
241 }
242
243 /* Set HDR Flag */
244 if(hasHdrInfo(src_img)) mIsHdrLayer = true;
245
246 if (isFormatYUV(gmeta.format) && exynosMPPVG) {
247 /*
248 * layer's sourceCrop should be aligned
249 */
250 uint32_t srcCropXAlign = exynosMPPVG->getSrcXOffsetAlign(src_img);
251 uint32_t srcCropYAlign = exynosMPPVG->getSrcYOffsetAlign(src_img);
252 uint32_t srcCropWidthAlign = exynosMPPVG->getSrcWidthAlign(src_img);
253 uint32_t srcCropHeightAlign = exynosMPPVG->getSrcHeightAlign(src_img);
254 mPreprocessedInfo.sourceCrop.left = pixel_align((int)mPreprocessedInfo.sourceCrop.left, srcCropXAlign);
255 mPreprocessedInfo.sourceCrop.top = pixel_align((int)mPreprocessedInfo.sourceCrop.top, srcCropYAlign);
256 mPreprocessedInfo.sourceCrop.right = mPreprocessedInfo.sourceCrop.left +
257 pixel_align_down(WIDTH(mPreprocessedInfo.sourceCrop), srcCropWidthAlign);
258 mPreprocessedInfo.sourceCrop.bottom = mPreprocessedInfo.sourceCrop.top +
259 pixel_align_down(HEIGHT(mPreprocessedInfo.sourceCrop), srcCropHeightAlign);
260 mPreprocessedInfo.preProcessed = true;
261 }
262
263 if (exynosMPPVG && ((getDrmMode(mLayerBuffer) != NO_DRM) ||
264 (mIsHdrLayer == true)))
265 {
266 if ((mDisplay->mDisplayControl.adjustDisplayFrame == true) &&
267 ((mSupportedMPPFlag & (MPP_LOGICAL_DPP_G | MPP_LOGICAL_DPP_VG | MPP_LOGICAL_DPP_VGFS | MPP_LOGICAL_DPP_VGRFS)) == 0))
268 {
269 /*
270 * M2mMPP should be used for DRM, HDR video
271 * layer's displayFrame is the source of DPP
272 */
273 uint32_t cropWidthAlign = exynosMPPVG->getSrcCropWidthAlign(src_img);
274 uint32_t cropHeightAlign = exynosMPPVG->getSrcCropHeightAlign(src_img);
275
276 mPreprocessedInfo.displayFrame.right = mDisplayFrame.left +
277 pixel_align(WIDTH(mDisplayFrame), cropWidthAlign);
278 mPreprocessedInfo.displayFrame.bottom = mDisplayFrame.top +
279 pixel_align(HEIGHT(mDisplayFrame), cropHeightAlign);
280
281 if (mPreprocessedInfo.displayFrame.right > (int)(mDisplay->mXres)) {
282 mPreprocessedInfo.displayFrame.left = mDisplay->mXres -
283 pixel_align(WIDTH(mPreprocessedInfo.displayFrame), cropWidthAlign);
284 mPreprocessedInfo.displayFrame.right = mDisplay->mXres;
285 }
286
287 if (mPreprocessedInfo.displayFrame.bottom > (int)(mDisplay->mYres)) {
288 mPreprocessedInfo.displayFrame.top = mDisplay->mYres -
289 pixel_align_down(HEIGHT(mPreprocessedInfo.displayFrame), cropHeightAlign);
290 mPreprocessedInfo.displayFrame.bottom = mDisplay->mYres;
291 }
292 }
293
294 uint32_t minDstWidth = exynosMPPVG->getDstMinWidth(dst_img);
295 uint32_t minDstHeight = exynosMPPVG->getDstMinHeight(dst_img);
296 if ((uint32_t)WIDTH(mDisplayFrame) < minDstWidth) {
297 ALOGI("%s DRM layer displayFrame width %d is smaller than otf minWidth %d",
298 mDisplay->mDisplayName.string(),
299 WIDTH(mDisplayFrame), minDstWidth);
300 mPreprocessedInfo.displayFrame.right = mDisplayFrame.left +
301 pixel_align(WIDTH(mDisplayFrame), minDstWidth);
302
303 if (mPreprocessedInfo.displayFrame.right > (int)(mDisplay->mXres)) {
304 mPreprocessedInfo.displayFrame.left = mDisplay->mXres -
305 pixel_align(WIDTH(mPreprocessedInfo.displayFrame), minDstWidth);
306 mPreprocessedInfo.displayFrame.right = mDisplay->mXres;
307 }
308 }
309 if ((uint32_t)HEIGHT(mDisplayFrame) < minDstHeight) {
310 ALOGI("%s DRM layer displayFrame height %d is smaller than vpp minHeight %d",
311 mDisplay->mDisplayName.string(),
312 HEIGHT(mDisplayFrame), minDstHeight);
313 mPreprocessedInfo.displayFrame.bottom = mDisplayFrame.top +
314 pixel_align(HEIGHT(mDisplayFrame), minDstHeight);
315
316 if (mPreprocessedInfo.displayFrame.bottom > (int)(mDisplay->mYres)) {
317 mPreprocessedInfo.displayFrame.top = mDisplay->mYres -
318 pixel_align(HEIGHT(mPreprocessedInfo.displayFrame), minDstHeight);
319 mPreprocessedInfo.displayFrame.bottom = mDisplay->mYres;
320 }
321 }
322 mPreprocessedInfo.preProcessed = true;
323 }
324
325 if (getDrmMode(mLayerBuffer) != NO_DRM) {
326 priority = ePriorityMax;
327 } else if (mIsHdrLayer) {
328 if (isFormatRgb(gmeta.format))
329 priority = ePriorityMax;
330 else
331 priority = ePriorityHigh;
332 } else if (isFormatYUV(gmeta.format)) {
333 priority = ePriorityHigh;
334 } else if ((mDisplay->mDisplayControl.cursorSupport == true) &&
335 (mCompositionType == HWC2_COMPOSITION_CURSOR)) {
336 priority = ePriorityMid;
337 } else {
338 priority = ePriorityLow;
339 }
340
341 if (mOverlayPriority != priority)
342 setGeometryChanged(GEOMETRY_LAYER_PRIORITY_CHANGED);
343
344 mOverlayPriority = priority;
345 return NO_ERROR;
346 }
347
setCursorPosition(int32_t x,int32_t y)348 int32_t ExynosLayer::setCursorPosition(int32_t x, int32_t y) {
349 return mDisplay->setCursorPositionAsync(x, y);
350 }
351
352
setLayerBuffer(buffer_handle_t buffer,int32_t acquireFence)353 int32_t ExynosLayer::setLayerBuffer(buffer_handle_t buffer, int32_t acquireFence) {
354
355 /* TODO : Exception here ? */
356 //TODO mGeometryChanged here
357
358 uint64_t internal_format = 0;
359
360 if (mDisplay->mPlugState == false)
361 buffer = NULL;
362
363 if (buffer != NULL) {
364 if (VendorGraphicBufferMeta::get_fd(buffer,0) < 0)
365 return HWC2_ERROR_BAD_LAYER;
366 }
367
368 VendorGraphicBufferMeta gmeta(mLayerBuffer);
369 internal_format = gmeta.format;
370
371 if ((mLayerBuffer == NULL) || (buffer == NULL))
372 setGeometryChanged(GEOMETRY_LAYER_UNKNOWN_CHANGED);
373 else {
374 if (getDrmMode(VendorGraphicBufferMeta::get_producer_usage(mLayerBuffer)) != getDrmMode(gmeta.producer_usage))
375 setGeometryChanged(GEOMETRY_LAYER_DRM_CHANGED);
376 if (VendorGraphicBufferMeta::get_format(mLayerBuffer) != gmeta.format)
377 setGeometryChanged(GEOMETRY_LAYER_FORMAT_CHANGED);
378 }
379
380 mLayerBuffer = buffer;
381 mPrevAcquireFence =
382 fence_close(mPrevAcquireFence, mDisplay, FENCE_TYPE_SRC_ACQUIRE, FENCE_IP_UNDEFINED);
383 mAcquireFence = fence_close(mAcquireFence, mDisplay, FENCE_TYPE_SRC_ACQUIRE, FENCE_IP_UNDEFINED);
384
385 mAcquireFence = hwcCheckFenceDebug(mDisplay, FENCE_TYPE_SRC_ACQUIRE, FENCE_IP_LAYER, acquireFence);
386 mPrevAcquireFence = hwcCheckFenceDebug(mDisplay, FENCE_TYPE_SRC_ACQUIRE, FENCE_IP_LAYER,
387 hwc_dup(mAcquireFence, mDisplay, FENCE_TYPE_SRC_ACQUIRE,
388 FENCE_IP_LAYER, true));
389 if (mReleaseFence >= 0)
390 HWC_LOGE(NULL, "Layer's release fence is not initialized");
391 mReleaseFence = -1;
392 #ifdef DISABLE_FENCE
393 if (mAcquireFence >= 0)
394 fence_close(mAcquireFence);
395 mAcquireFence = -1;
396 #endif
397 bool compressed = isAFBCCompressed(mLayerBuffer);
398 if (mCompressed != compressed)
399 setGeometryChanged(GEOMETRY_LAYER_COMPRESSED_CHANGED);
400 mCompressed = compressed;
401
402 if (buffer != NULL) {
403 /*
404 * HAL_DATASPACE_V0_JFIF = HAL_DATASPACE_STANDARD_BT601_625 |
405 * HAL_DATASPACE_TRANSFER_SMPTE_170M | HAL_DATASPACE_RANGE_FULL,
406 */
407 if (gmeta.format == HAL_PIXEL_FORMAT_EXYNOS_YCrCb_420_SP_M_FULL)
408 setLayerDataspace(HAL_DATASPACE_V0_JFIF);
409 } else {
410 setLayerDataspace(HAL_DATASPACE_UNKNOWN);
411 }
412
413 HDEBUGLOGD(eDebugFence,
414 "layers bufferHandle: %p, mDataSpace: 0x%8x, acquireFence: %d, afbc: %d, "
415 "internal_format: 0x%" PRIx64 "",
416 mLayerBuffer, mDataSpace, mAcquireFence, mCompressed, internal_format);
417
418 /* Update fps */
419 checkFps();
420
421 return 0;
422 }
423
424
setLayerSurfaceDamage(hwc_region_t damage)425 int32_t ExynosLayer::setLayerSurfaceDamage(hwc_region_t damage) {
426
427 mDamageNum = damage.numRects;
428 mDamageRects.clear();
429
430 if (mDamageNum == 0) return 0;
431
432 for (size_t i = 0; i<mDamageNum; i++){
433 mDamageRects.push_back(damage.rects[i]);
434 }
435
436 return 0;
437 }
438
setLayerBlendMode(int32_t mode)439 int32_t ExynosLayer::setLayerBlendMode(int32_t /*hwc2_blend_mode_t*/ mode) {
440
441 //TODO mGeometryChanged here
442 if (mode < 0)
443 return HWC2_ERROR_BAD_PARAMETER;
444 if (mBlending != mode)
445 setGeometryChanged(GEOMETRY_LAYER_BLEND_CHANGED);
446 mBlending = mode;
447 return HWC2_ERROR_NONE;
448 }
449
450
setLayerColor(hwc_color_t color)451 int32_t ExynosLayer::setLayerColor(hwc_color_t color) {
452 /* TODO : Implementation here */
453 mColor = color;
454 return 0;
455 }
456
setLayerCompositionType(int32_t type)457 int32_t ExynosLayer::setLayerCompositionType(int32_t /*hwc2_composition_t*/ type) {
458
459 if (type < 0)
460 return HWC2_ERROR_BAD_PARAMETER;
461
462 // FIXME: HWC2_COMPOSITION_SCREENSHOT is not defined in AOSP
463 // HWC guys should fix this.
464 #if 0
465 if (mDisplay->mType == HWC_DISPLAY_PRIMARY)
466 if (type == HWC2_COMPOSITION_SCREENSHOT)
467 type = HWC2_COMPOSITION_DEVICE;
468 #endif
469
470 if (type != mCompositionType) {
471 setGeometryChanged(GEOMETRY_LAYER_TYPE_CHANGED);
472 }
473
474 mCompositionType = type;
475
476 return HWC2_ERROR_NONE;
477 }
478
setLayerDataspace(int32_t dataspace)479 int32_t ExynosLayer::setLayerDataspace(int32_t /*android_dataspace_t*/ dataspace) {
480 android_dataspace currentDataSpace = (android_dataspace_t)dataspace;
481 if ((mLayerBuffer != NULL) && (VendorGraphicBufferMeta::get_format(mLayerBuffer) == HAL_PIXEL_FORMAT_EXYNOS_YCrCb_420_SP_M_FULL))
482 currentDataSpace = HAL_DATASPACE_V0_JFIF;
483 else {
484 /* Change legacy dataspace */
485 switch (dataspace) {
486 case HAL_DATASPACE_SRGB_LINEAR:
487 currentDataSpace = HAL_DATASPACE_V0_SRGB_LINEAR;
488 break;
489 case HAL_DATASPACE_SRGB:
490 currentDataSpace = HAL_DATASPACE_V0_SRGB;
491 break;
492 case HAL_DATASPACE_JFIF:
493 currentDataSpace = HAL_DATASPACE_V0_JFIF;
494 break;
495 case HAL_DATASPACE_BT601_625:
496 currentDataSpace = HAL_DATASPACE_V0_BT601_625;
497 break;
498 case HAL_DATASPACE_BT601_525:
499 currentDataSpace = HAL_DATASPACE_V0_BT601_525;
500 break;
501 case HAL_DATASPACE_BT709:
502 currentDataSpace = HAL_DATASPACE_V0_BT709;
503 break;
504 default:
505 currentDataSpace = (android_dataspace)dataspace;
506 break;
507 }
508 }
509
510 if (currentDataSpace != mDataSpace) {
511 setGeometryChanged(GEOMETRY_LAYER_DATASPACE_CHANGED);
512 }
513 mDataSpace = currentDataSpace;
514
515 return HWC2_ERROR_NONE;
516 }
517
setLayerDisplayFrame(hwc_rect_t frame)518 int32_t ExynosLayer::setLayerDisplayFrame(hwc_rect_t frame) {
519
520 if ((frame.left != mDisplayFrame.left) ||
521 (frame.top != mDisplayFrame.top) ||
522 (frame.right != mDisplayFrame.right) ||
523 (frame.bottom != mDisplayFrame.bottom))
524 setGeometryChanged(GEOMETRY_LAYER_DISPLAYFRAME_CHANGED);
525 mDisplayFrame = frame;
526
527 return HWC2_ERROR_NONE;
528 }
529
setLayerPlaneAlpha(float alpha)530 int32_t ExynosLayer::setLayerPlaneAlpha(float alpha) {
531
532 if (alpha < 0.0)
533 return HWC2_ERROR_BAD_LAYER;
534
535 if ((mPlaneAlpha != alpha) && ((mPlaneAlpha == 0.0) || (alpha == 0.0)))
536 setGeometryChanged(GEOMETRY_LAYER_IGNORE_CHANGED);
537
538 mPlaneAlpha = alpha;
539
540 if (mPlaneAlpha > 0.0)
541 mLayerFlag &= ~(EXYNOS_HWC_IGNORE_LAYER);
542 else
543 mLayerFlag |= EXYNOS_HWC_IGNORE_LAYER;
544
545 return HWC2_ERROR_NONE;
546 }
547
setLayerSidebandStream(const native_handle_t * __unused stream)548 int32_t ExynosLayer::setLayerSidebandStream(const native_handle_t* __unused stream) {
549 return HWC2_ERROR_NONE;
550 }
551
setLayerSourceCrop(hwc_frect_t crop)552 int32_t ExynosLayer::setLayerSourceCrop(hwc_frect_t crop) {
553
554 if ((crop.left != mSourceCrop.left) ||
555 (crop.top != mSourceCrop.top) ||
556 (crop.right != mSourceCrop.right) ||
557 (crop.bottom != mSourceCrop.bottom)) {
558 setGeometryChanged(GEOMETRY_LAYER_SOURCECROP_CHANGED);
559 mSourceCrop = crop;
560 }
561
562 return HWC2_ERROR_NONE;
563 }
564
setLayerTransform(int32_t transform)565 int32_t ExynosLayer::setLayerTransform(int32_t /*hwc_transform_t*/ transform) {
566
567 if (mTransform != transform) {
568 setGeometryChanged(GEOMETRY_LAYER_TRANSFORM_CHANGED);
569 mTransform = transform;
570 }
571
572 return HWC2_ERROR_NONE;
573 }
574
setLayerVisibleRegion(hwc_region_t visible)575 int32_t ExynosLayer::setLayerVisibleRegion(hwc_region_t visible) {
576
577 mVisibleRegionScreen = visible;
578
579 return HWC2_ERROR_NONE;
580 }
581
setLayerZOrder(uint32_t z)582 int32_t ExynosLayer::setLayerZOrder(uint32_t z) {
583 if (mZOrder != z) {
584 setGeometryChanged(GEOMETRY_LAYER_ZORDER_CHANGED);
585 mZOrder = z;
586 }
587 return HWC2_ERROR_NONE;
588 }
589
setLayerPerFrameMetadata(uint32_t numElements,const int32_t * keys,const float * metadata)590 int32_t ExynosLayer::setLayerPerFrameMetadata(uint32_t numElements,
591 const int32_t* /*hw2_per_frame_metadata_key_t*/ keys, const float* metadata)
592 {
593 if (allocMetaParcel() != NO_ERROR)
594 return -1;
595 unsigned int multipliedVal = 50000;
596 mMetaParcel->eType =
597 static_cast<ExynosVideoInfoType>(mMetaParcel->eType | VIDEO_INFO_TYPE_HDR_STATIC);
598 for (uint32_t i = 0; i < numElements; i++) {
599 HDEBUGLOGD(eDebugLayer, "HWC2: setLayerPerFrameMetadata key(%d), value(%7.5f)",
600 keys[i], metadata[i]);
601 switch (keys[i]) {
602 case HWC2_DISPLAY_RED_PRIMARY_X:
603 mMetaParcel->sHdrStaticInfo.sType1.mR.x =
604 (unsigned int)(metadata[i] * multipliedVal);
605 break;
606 case HWC2_DISPLAY_RED_PRIMARY_Y:
607 mMetaParcel->sHdrStaticInfo.sType1.mR.y =
608 (unsigned int)(metadata[i] * multipliedVal);
609 break;
610 case HWC2_DISPLAY_GREEN_PRIMARY_X:
611 mMetaParcel->sHdrStaticInfo.sType1.mG.x =
612 (unsigned int)(metadata[i] * multipliedVal);
613 break;
614 case HWC2_DISPLAY_GREEN_PRIMARY_Y:
615 mMetaParcel->sHdrStaticInfo.sType1.mG.y =
616 (unsigned int)(metadata[i] * multipliedVal);
617 break;
618 case HWC2_DISPLAY_BLUE_PRIMARY_X:
619 mMetaParcel->sHdrStaticInfo.sType1.mB.x =
620 (unsigned int)(metadata[i] * multipliedVal);
621 break;
622 case HWC2_DISPLAY_BLUE_PRIMARY_Y:
623 mMetaParcel->sHdrStaticInfo.sType1.mB.y =
624 (unsigned int)(metadata[i] * multipliedVal);
625 break;
626 case HWC2_WHITE_POINT_X:
627 mMetaParcel->sHdrStaticInfo.sType1.mW.x =
628 (unsigned int)(metadata[i] * multipliedVal);
629 break;
630 case HWC2_WHITE_POINT_Y:
631 mMetaParcel->sHdrStaticInfo.sType1.mW.y =
632 (unsigned int)(metadata[i] * multipliedVal);
633 break;
634 case HWC2_MAX_LUMINANCE:
635 mMetaParcel->sHdrStaticInfo.sType1.mMaxDisplayLuminance =
636 (unsigned int)(metadata[i] * 10000);
637 break;
638 case HWC2_MIN_LUMINANCE:
639 mMetaParcel->sHdrStaticInfo.sType1.mMinDisplayLuminance =
640 (unsigned int)(metadata[i] * 10000);
641 break;
642 case HWC2_MAX_CONTENT_LIGHT_LEVEL:
643 /* Should be checked */
644 mMetaParcel->sHdrStaticInfo.sType1.mMaxContentLightLevel =
645 (unsigned int)(metadata[i]);
646 break;
647 case HWC2_MAX_FRAME_AVERAGE_LIGHT_LEVEL:
648 /* Should be checked */
649 mMetaParcel->sHdrStaticInfo.sType1.mMaxFrameAverageLightLevel =
650 (unsigned int)(metadata[i]);
651 break;
652 default:
653 return HWC2_ERROR_UNSUPPORTED;
654 }
655 }
656 return NO_ERROR;
657 }
658
setLayerPerFrameMetadataBlobs(uint32_t numElements,const int32_t * keys,const uint32_t * sizes,const uint8_t * metadata)659 int32_t ExynosLayer::setLayerPerFrameMetadataBlobs(uint32_t numElements, const int32_t* keys, const uint32_t* sizes,
660 const uint8_t* metadata)
661 {
662 const uint8_t *metadata_start = metadata;
663 for (uint32_t i = 0; i < numElements; i++) {
664 HDEBUGLOGD(eDebugLayer, "HWC2: setLayerPerFrameMetadataBlobs key(%d)", keys[i]);
665 switch (keys[i]) {
666 case HWC2_HDR10_PLUS_SEI:
667 if (allocMetaParcel() == NO_ERROR) {
668 mMetaParcel->eType =
669 static_cast<ExynosVideoInfoType>(mMetaParcel->eType | VIDEO_INFO_TYPE_HDR_DYNAMIC);
670 ExynosHdrDynamicInfo *info = &(mMetaParcel->sHdrDynamicInfo);
671 Exynos_parsing_user_data_registered_itu_t_t35(info, (void *)metadata_start);
672 } else {
673 ALOGE("Layer has no metaParcel!");
674 return HWC2_ERROR_UNSUPPORTED;
675 }
676 break;
677 default:
678 return HWC2_ERROR_BAD_PARAMETER;
679 }
680 metadata_start += sizes[i];
681 }
682 return HWC2_ERROR_NONE;
683 }
684
setLayerColorTransform(const float * matrix)685 int32_t ExynosLayer::setLayerColorTransform(const float* matrix)
686 {
687 mLayerColorTransform.enable = true;
688 for (uint32_t i = 0; i < TRANSFORM_MAT_SIZE; i++)
689 {
690 mLayerColorTransform.mat[i] = matrix[i];
691 }
692
693 return 0;
694 }
695
setLayerGenericMetadata(hwc2_layer_t __unused layer,uint32_t __unused keyLength,const char * __unused key,bool __unused mandatory,uint32_t __unused valueLength,const uint8_t * __unused value)696 int32_t ExynosLayer::setLayerGenericMetadata(hwc2_layer_t __unused layer,
697 uint32_t __unused keyLength, const char* __unused key,
698 bool __unused mandatory, uint32_t __unused valueLength, const uint8_t* __unused value)
699 {
700 return HWC2_ERROR_UNSUPPORTED;
701 }
702
resetValidateData()703 void ExynosLayer::resetValidateData()
704 {
705 mValidateCompositionType = HWC2_COMPOSITION_INVALID;
706 mOtfMPP = NULL;
707 mM2mMPP = NULL;
708 mOverlayInfo = 0x0;
709 mWindowIndex = 0;
710 }
711
setSrcExynosImage(exynos_image * src_img)712 int32_t ExynosLayer::setSrcExynosImage(exynos_image *src_img)
713 {
714 buffer_handle_t handle = mLayerBuffer;
715 if (isDimLayer()) {
716 src_img->format = HAL_PIXEL_FORMAT_RGBA_8888;
717 src_img->usageFlags = 0xb00;
718 src_img->bufferHandle = 0;
719
720 src_img->x = 0;
721 src_img->y = 0;
722
723 if (mDisplay != NULL) {
724 src_img->fullWidth = src_img->w = mDisplay->mXres;
725 src_img->fullHeight = src_img->h = mDisplay->mYres;
726 } else {
727 src_img->fullWidth = src_img->w = 1440;
728 src_img->fullHeight = src_img->h = 2560;
729 }
730
731 src_img->layerFlags = mLayerFlag;
732 src_img->acquireFenceFd = mAcquireFence;
733 src_img->releaseFenceFd = -1;
734 src_img->dataSpace = HAL_DATASPACE_V0_SRGB;
735 src_img->blending = mBlending;
736 src_img->transform = mTransform;
737 src_img->compressed = mCompressed;
738 src_img->planeAlpha = mPlaneAlpha;
739 src_img->zOrder = mZOrder;
740
741
742 return NO_ERROR;
743 }
744
745 if (handle == NULL) {
746 src_img->fullWidth = 0;
747 src_img->fullHeight = 0;
748 src_img->format = 0;
749 src_img->usageFlags = 0x0;
750 src_img->bufferHandle = handle;
751 } else {
752 VendorGraphicBufferMeta gmeta(handle);
753
754 if ((mPreprocessedInfo.interlacedType == V4L2_FIELD_INTERLACED_TB) ||
755 (mPreprocessedInfo.interlacedType == V4L2_FIELD_INTERLACED_BT))
756 {
757 src_img->fullWidth = (gmeta.stride * 2);
758 src_img->fullHeight = pixel_align_down((gmeta.vstride / 2), 2);
759 } else {
760 src_img->fullWidth = gmeta.stride;
761 src_img->fullHeight = gmeta.vstride;
762 }
763 if (!mPreprocessedInfo.mUsePrivateFormat)
764 src_img->format = gmeta.format;
765 else
766 src_img->format = mPreprocessedInfo.mPrivateFormat;
767 src_img->usageFlags = gmeta.producer_usage;
768 src_img->bufferHandle = handle;
769 }
770 src_img->x = (int)mPreprocessedInfo.sourceCrop.left;
771 src_img->y = (int)mPreprocessedInfo.sourceCrop.top;
772 src_img->w = (int)mPreprocessedInfo.sourceCrop.right - (int)mPreprocessedInfo.sourceCrop.left;
773 src_img->h = (int)mPreprocessedInfo.sourceCrop.bottom - (int)mPreprocessedInfo.sourceCrop.top;
774 if ((mPreprocessedInfo.interlacedType == V4L2_FIELD_INTERLACED_TB) ||
775 (mPreprocessedInfo.interlacedType == V4L2_FIELD_INTERLACED_BT))
776 {
777 while ((src_img->h % 2 != 0) ||
778 (src_img->h > src_img->fullHeight)) {
779 src_img->h -= 1;
780 }
781 }
782 src_img->layerFlags = mLayerFlag;
783 src_img->acquireFenceFd = mAcquireFence;
784 src_img->releaseFenceFd = -1;
785
786 src_img->dataSpace = mDataSpace;
787 if(src_img->dataSpace == HAL_DATASPACE_UNKNOWN)
788 src_img->dataSpace = HAL_DATASPACE_V0_SRGB;
789
790 src_img->blending = mBlending;
791 src_img->transform = mTransform;
792 src_img->compressed = mCompressed;
793 src_img->planeAlpha = mPlaneAlpha;
794 src_img->zOrder = mZOrder;
795 /* Copy HDR metadata */
796 memset(&(src_img->metaParcel), 0, sizeof(src_img->metaParcel));
797 src_img->metaType = VIDEO_INFO_TYPE_INVALID;
798 if (mMetaParcel != NULL) {
799 memcpy(&(src_img->metaParcel), mMetaParcel, sizeof(src_img->metaParcel));
800 src_img->metaType = mMetaParcel->eType;
801 src_img->hasMetaParcel = true;
802 } else {
803 src_img->hasMetaParcel = false;
804 }
805
806 src_img->needColorTransform = mLayerColorTransform.enable;
807
808 return NO_ERROR;
809 }
810
setDstExynosImage(exynos_image * dst_img)811 int32_t ExynosLayer::setDstExynosImage(exynos_image *dst_img)
812 {
813 buffer_handle_t handle = mLayerBuffer;
814
815 if (handle == NULL) {
816 dst_img->usageFlags = 0x0;
817 } else {
818 dst_img->usageFlags = VendorGraphicBufferMeta::get_producer_usage(handle);
819 }
820
821 if (isDimLayer()) {
822 dst_img->usageFlags = 0xb00;
823 }
824
825 dst_img->format = DEFAULT_MPP_DST_FORMAT;
826 dst_img->x = mPreprocessedInfo.displayFrame.left;
827 dst_img->y = mPreprocessedInfo.displayFrame.top;
828 dst_img->w = (mPreprocessedInfo.displayFrame.right - mPreprocessedInfo.displayFrame.left);
829 dst_img->h = (mPreprocessedInfo.displayFrame.bottom - mPreprocessedInfo.displayFrame.top);
830 dst_img->layerFlags = mLayerFlag;
831 dst_img->acquireFenceFd = -1;
832 dst_img->releaseFenceFd = -1;
833 dst_img->bufferHandle = NULL;
834 dst_img->dataSpace = HAL_DATASPACE_UNKNOWN;
835 if (mDisplay != NULL) {
836 dst_img->fullWidth = mDisplay->mXres;
837 dst_img->fullHeight = mDisplay->mYres;
838 if (mDisplay->mColorMode != HAL_COLOR_MODE_NATIVE) {
839 dst_img->dataSpace = colorModeToDataspace(mDisplay->mColorMode);
840 } else {
841 if (hasHdrInfo(mDataSpace)) {
842 android_dataspace hdrDataSpace =
843 (android_dataspace)(HAL_DATASPACE_STANDARD_DCI_P3 | HAL_DATASPACE_TRANSFER_GAMMA2_2 | HAL_DATASPACE_RANGE_LIMITED);
844 if (mDisplay->mType == HWC_DISPLAY_EXTERNAL) {
845 ExynosExternalDisplay *externalDisplay = (ExynosExternalDisplay*)mDisplay;
846 if (externalDisplay->mExternalHdrSupported == true)
847 dst_img->dataSpace = HAL_DATASPACE_UNKNOWN;
848 else
849 dst_img->dataSpace = hdrDataSpace;
850 } else {
851 dst_img->dataSpace = hdrDataSpace;
852 }
853 }
854 }
855 } else {
856 HWC_LOGE(NULL, "mDisplay is NULL");
857 }
858 dst_img->blending = mBlending;
859 dst_img->transform = 0;
860 dst_img->compressed = 0;
861 dst_img->planeAlpha = mPlaneAlpha;
862 dst_img->zOrder = mZOrder;
863
864 /* Copy HDR metadata */
865 memset(&(dst_img->metaParcel), 0, sizeof(dst_img->metaParcel));
866 dst_img->metaType = VIDEO_INFO_TYPE_INVALID;
867 if (mMetaParcel != NULL) {
868 memcpy(&(dst_img->metaParcel), mMetaParcel, sizeof(dst_img->metaParcel));
869 dst_img->metaType = mMetaParcel->eType;
870 dst_img->hasMetaParcel = true;
871 } else {
872 dst_img->hasMetaParcel = false;
873 }
874
875 return NO_ERROR;
876 }
877
resetAssignedResource()878 int32_t ExynosLayer::resetAssignedResource()
879 {
880 int32_t ret = NO_ERROR;
881 if (mM2mMPP != NULL) {
882 HDEBUGLOGD(eDebugResourceManager, "\t\t %s mpp is reset", mM2mMPP->mName.string());
883 mM2mMPP->resetAssignedState(this);
884 mM2mMPP = NULL;
885 }
886 if (mOtfMPP != NULL) {
887 HDEBUGLOGD(eDebugResourceManager, "\t\t %s mpp is reset", mOtfMPP->mName.string());
888 mOtfMPP->resetAssignedState();
889 mOtfMPP = NULL;
890 }
891 return ret;
892 }
893
checkDownscaleCap(uint32_t bts_refresh_rate)894 bool ExynosLayer::checkDownscaleCap(uint32_t bts_refresh_rate)
895 {
896 if (mOtfMPP == nullptr) return true;
897
898 exynos_image src_img;
899 exynos_image dst_img;
900
901 setSrcExynosImage(&src_img);
902 setDstExynosImage(&dst_img);
903
904 const bool isPerpendicular = !!(src_img.transform & HAL_TRANSFORM_ROT_90);
905 const uint32_t srcWidth = isPerpendicular ? src_img.h : src_img.w;
906 const uint32_t srcHeight = isPerpendicular ? src_img.w : src_img.h;
907 const bool scaleDown = (srcWidth > dst_img.w || srcHeight > dst_img.h);
908
909 if (!scaleDown) return true;
910
911 const float resolution = float(src_img.w) * float(src_img.h) * bts_refresh_rate / 1000;
912
913 return mOtfMPP->checkDownscaleCap(resolution, float(dst_img.h) / float(mDisplay->mYres));
914 }
915
setSrcAcquireFence()916 void ExynosLayer::setSrcAcquireFence() {
917 if (mAcquireFence == -1 && mPrevAcquireFence != -1) {
918 mAcquireFence = hwcCheckFenceDebug(mDisplay, FENCE_TYPE_SRC_ACQUIRE, FENCE_IP_LAYER,
919 hwc_dup(mPrevAcquireFence, mDisplay,
920 FENCE_TYPE_SRC_ACQUIRE, FENCE_IP_LAYER));
921 } else if (mAcquireFence != -1) {
922 setFenceInfo(mAcquireFence, mDisplay, FENCE_TYPE_SRC_ACQUIRE, FENCE_IP_LAYER, FENCE_FROM);
923 }
924 }
925
dump(String8 & result)926 void ExynosLayer::dump(String8& result)
927 {
928 int format = HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED;
929 int32_t fd, fd1, fd2;
930 if (mLayerBuffer != NULL)
931 {
932 VendorGraphicBufferMeta gmeta(mLayerBuffer);
933 format = gmeta.format;
934 fd = gmeta.fd;
935 fd1 = gmeta.fd1;
936 fd2 = gmeta.fd2;
937 } else {
938 format = HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED;
939 fd = -1;
940 fd1 = -1;
941 fd2 = -1;
942 }
943
944 {
945 TableBuilder tb;
946 tb.add("zOrder", mZOrder)
947 .add("priority", mOverlayPriority);
948 if (mCompositionType == HWC2_COMPOSITION_SOLID_COLOR) {
949 tb.add("color", std::vector<uint64_t>({mColor.r, mColor.g, mColor.b, mColor.a}), true);
950 } else {
951 tb.add("handle", mLayerBuffer)
952 .add("fd", std::vector<int>({fd, fd1, fd2}))
953 .add("AFBC", static_cast<bool>(mCompressed));
954 }
955 tb.add("format", getFormatStr(format, mCompressed ? AFBC : 0).string())
956 .add("dataSpace", mDataSpace, true)
957 .add("colorTr", mLayerColorTransform.enable)
958 .add("blend", mBlending, true)
959 .add("planeAlpha", mPlaneAlpha)
960 .add("fps", mFps);
961 result.append(tb.build().c_str());
962 }
963
964 result.append(TableBuilder()
965 .add("sourceCrop",
966 std::vector<double>({mPreprocessedInfo.sourceCrop.left,
967 mPreprocessedInfo.sourceCrop.top,
968 mPreprocessedInfo.sourceCrop.right,
969 mPreprocessedInfo.sourceCrop.bottom}))
970 .add("dispFrame",
971 std::vector<int>({mPreprocessedInfo.displayFrame.left,
972 mPreprocessedInfo.displayFrame.top,
973 mPreprocessedInfo.displayFrame.right,
974 mPreprocessedInfo.displayFrame.bottom}))
975 .add("tr", mTransform, true)
976 .add("windowIndex", mWindowIndex)
977 .add("type", mCompositionType)
978 .add("exynosType", mExynosCompositionType)
979 .add("validateType", mValidateCompositionType)
980 .add("overlayInfo", mOverlayInfo, true)
981 .add("supportedMPPFlag", mSupportedMPPFlag, true)
982 .build()
983 .c_str());
984
985 if ((mDisplay != NULL) && (mDisplay->mResourceManager != NULL)) {
986 result.appendFormat("MPPFlags for otfMPP\n");
987 for (uint32_t i = 0; i < mDisplay->mResourceManager->getOtfMPPSize(); i++) {
988 result.appendFormat("[%s: 0x%" PRIx64 "] ", mDisplay->mResourceManager->getOtfMPP(i)->mName.string(),
989 mCheckMPPFlag[mDisplay->mResourceManager->getOtfMPP(i)->mLogicalType]);
990 }
991 result.appendFormat("\n");
992 result.appendFormat("MPPFlags for m2mMPP\n");
993 for (uint32_t i = 0; i < mDisplay->mResourceManager->getM2mMPPSize(); i++) {
994 result.appendFormat("[%s: 0x%" PRIx64 "] ", mDisplay->mResourceManager->getM2mMPP(i)->mName.string(),
995 mCheckMPPFlag[mDisplay->mResourceManager->getM2mMPP(i)->mLogicalType]);
996 if ((i!=0) && (i%4==0)) result.appendFormat("\n");
997 }
998 result.appendFormat("\n");
999 }
1000 result.appendFormat("acquireFence: %d\n", mAcquireFence);
1001 if ((mOtfMPP == NULL) && (mM2mMPP == NULL))
1002 result.appendFormat("\tresource is not assigned.\n");
1003 if (mOtfMPP != NULL)
1004 result.appendFormat("\tassignedMPP: %s\n", mOtfMPP->mName.string());
1005 if (mM2mMPP != NULL)
1006 result.appendFormat("\tassignedM2mMPP: %s\n", mM2mMPP->mName.string());
1007 result.appendFormat("\tdump midImg\n");
1008 dumpExynosImage(result, mMidImg);
1009
1010 }
1011
printLayer()1012 void ExynosLayer::printLayer()
1013 {
1014 int format = HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED;
1015 int32_t fd, fd1, fd2;
1016 String8 result;
1017 if (mLayerBuffer != NULL)
1018 {
1019 VendorGraphicBufferMeta gmeta(mLayerBuffer);
1020 format = gmeta.format;
1021 fd = gmeta.fd;
1022 fd1 = gmeta.fd1;
1023 fd2 = gmeta.fd2;
1024 } else {
1025 format = HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED;
1026 fd = -1;
1027 fd1 = -1;
1028 fd2 = -1;
1029 }
1030 result.appendFormat("handle: %p [fd: %d, %d, %d], acquireFence: %d, tr: 0x%2x, AFBC: %1d, dataSpace: 0x%8x, format: %s\n",
1031 mLayerBuffer, fd, fd1, fd2, mAcquireFence, mTransform, mCompressed, mDataSpace, getFormatStr(format, mCompressed? AFBC : 0).string());
1032 result.appendFormat("\tblend: 0x%4x, planeAlpha: %3.1f, zOrder: %d, color[0x%2x, 0x%2x, 0x%2x, 0x%2x]\n",
1033 mBlending, mPlaneAlpha, mZOrder, mColor.r, mColor.g, mColor.b, mColor.a);
1034 result.appendFormat("\tfps: %2d, priority: %d, windowIndex: %d\n", mFps, mOverlayPriority, mWindowIndex);
1035 result.appendFormat("\tsourceCrop[%7.1f,%7.1f,%7.1f,%7.1f], dispFrame[%5d,%5d,%5d,%5d]\n",
1036 mSourceCrop.left, mSourceCrop.top, mSourceCrop.right, mSourceCrop.bottom,
1037 mDisplayFrame.left, mDisplayFrame.top, mDisplayFrame.right, mDisplayFrame.bottom);
1038 result.appendFormat("\ttype: %2d, exynosType: %2d, validateType: %2d\n",
1039 mCompositionType, mExynosCompositionType, mValidateCompositionType);
1040 result.appendFormat("\toverlayInfo: 0x%8x, supportedMPPFlag: 0x%8x, geometryChanged: 0x%" PRIx64 "\n",
1041 mOverlayInfo, mSupportedMPPFlag, mGeometryChanged);
1042
1043 if ((mDisplay != NULL) && (mDisplay->mResourceManager != NULL)) {
1044 result.appendFormat("MPPFlags for otfMPP\n");
1045 for (uint32_t i = 0; i < mDisplay->mResourceManager->getOtfMPPSize(); i++) {
1046 result.appendFormat("[%s: 0x%" PRIx64 "] ", mDisplay->mResourceManager->getOtfMPP(i)->mName.string(),
1047 mCheckMPPFlag[mDisplay->mResourceManager->getOtfMPP(i)->mLogicalType]);
1048 }
1049 result.appendFormat("\n");
1050 result.appendFormat("MPPFlags for m2mMPP\n");
1051 for (uint32_t i = 0; i < mDisplay->mResourceManager->getM2mMPPSize(); i++) {
1052 result.appendFormat("[%s: 0x%" PRIx64 "] ", mDisplay->mResourceManager->getM2mMPP(i)->mName.string(),
1053 mCheckMPPFlag[mDisplay->mResourceManager->getM2mMPP(i)->mLogicalType]);
1054 if ((i!=0) && (i%4==0)) result.appendFormat("\n");
1055 }
1056 result.appendFormat("\n");
1057 }
1058
1059 ALOGD("%s", result.string());
1060 result.clear();
1061
1062 if ((mOtfMPP == NULL) && (mM2mMPP == NULL))
1063 ALOGD("\tresource is not assigned.");
1064 if (mOtfMPP != NULL)
1065 ALOGD("\tassignedMPP: %s", mOtfMPP->mName.string());
1066 if (mM2mMPP != NULL)
1067 ALOGD("\tassignedM2mMPP: %s", mM2mMPP->mName.string());
1068 ALOGD("\t++ dump midImg ++");
1069 dumpExynosImage(result, mMidImg);
1070 ALOGD("%s", result.string());
1071
1072 }
1073
setGeometryChanged(uint64_t changedBit)1074 void ExynosLayer::setGeometryChanged(uint64_t changedBit)
1075 {
1076 mGeometryChanged |= changedBit;
1077 mDisplay->setGeometryChanged(changedBit);
1078 }
1079
allocMetaParcel()1080 int ExynosLayer::allocMetaParcel()
1081 {
1082 /* Already allocated */
1083 if ((mMetaParcelFd >= 0) &&
1084 (mMetaParcel != NULL))
1085 return NO_ERROR;
1086
1087 if (mMetaParcelFd < 0) {
1088 int ionFd = exynos_ion_open();
1089 if (ionFd >= 0) {
1090 mMetaParcelFd = exynos_ion_alloc(ionFd, sizeof(ExynosVideoMeta), EXYNOS_ION_HEAP_SYSTEM_MASK, 0);
1091 if (mMetaParcelFd < 0) {
1092 ALOGE("Failed to ion alloc for metadata parcel");
1093 return -1;
1094 }
1095 exynos_ion_close(ionFd);
1096 } else {
1097 ALOGE("Failed to open ion fd");
1098 return -1;
1099 }
1100 }
1101
1102 mMetaParcel =
1103 (ExynosVideoMeta*)mmap(0, sizeof(ExynosVideoMeta), PROT_READ|PROT_WRITE, MAP_SHARED, mMetaParcelFd, 0);
1104 if (mMetaParcel == NULL) {
1105 ALOGE("Failed to map metadata parcel");
1106 return -1;
1107 }
1108
1109 return NO_ERROR;
1110 }
1111
isDimLayer()1112 bool ExynosLayer::isDimLayer()
1113 {
1114 if (mLayerFlag & EXYNOS_HWC_DIM_LAYER)
1115 return true;
1116 return false;
1117 }
1118