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