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