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