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