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