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