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 /**
18 * Project HWC 2.0 Design
19 */
20 #define ATRACE_TAG (ATRACE_TAG_GRAPHICS | ATRACE_TAG_HAL)
21 #include <utils/Errors.h>
22 #include <sync/sync.h>
23 #include <sys/mman.h>
24 #include <cutils/properties.h>
25 #include "ExynosMPP.h"
26 #include "ExynosResourceRestriction.h"
27 #include <hardware/hwcomposer_defs.h>
28 #include <math.h>
29 #include "VendorGraphicBuffer.h"
30 #include "ExynosHWCDebug.h"
31 #include "ExynosDisplay.h"
32 #include "ExynosVirtualDisplay.h"
33 #include "ExynosLayer.h"
34 #include "ExynosHWCHelper.h"
35 #include "exynos_sync.h"
36 #include "ExynosResourceManager.h"
37
38 /**
39 * ExynosMPP implementation
40 *
41 * Abstraction class for HW Resource
42 */
43
44 using namespace android;
45 using namespace vendor::graphics;
46
47 int ExynosMPP::mainDisplayWidth = 0;
48 int ExynosMPP::mainDisplayHeight = 0;
49 extern struct exynos_hwc_control exynosHWCControl;
50 #ifndef USE_MODULE_ATTR
51 extern feature_support_t feature_table[];
52 #endif
53
dumpExynosMPPImgInfo(uint32_t type,exynos_mpp_img_info & imgInfo)54 void dumpExynosMPPImgInfo(uint32_t type, exynos_mpp_img_info &imgInfo)
55 {
56 HDEBUGLOGD(type, "\tbuffer: %p, bufferType: %d",
57 imgInfo.bufferHandle, imgInfo.bufferType);
58 }
59
exynosMPPSourceComp(const ExynosMPPSource * l,const ExynosMPPSource * r)60 bool exynosMPPSourceComp(const ExynosMPPSource* l, const ExynosMPPSource* r)
61 {
62 if (l == NULL || r == NULL) {
63 HWC_LOGE(NULL,"exynosMPP compare error");
64 return 0;
65 }
66 return (l->mSrcImg.zOrder < r->mSrcImg.zOrder);
67 }
68
dump(const restriction_size_t & restrictionSize,String8 & result)69 void dump(const restriction_size_t &restrictionSize, String8 &result) {
70 result.appendFormat(" maxDownScale = %u, maxUpscale = %u\n", restrictionSize.maxDownScale,
71 restrictionSize.maxUpScale);
72 result.appendFormat(" maxFullWidth = %u, maxFullHeight = %u\n", restrictionSize.maxFullWidth,
73 restrictionSize.maxFullHeight);
74 result.appendFormat(" minFullWidth = %u, minFullHeight = %u\n", restrictionSize.minFullWidth,
75 restrictionSize.minFullHeight);
76 result.appendFormat(" fullWidthAlign = %u, fullHeightAlign = %u\n",
77 restrictionSize.fullWidthAlign, restrictionSize.fullHeightAlign);
78 result.appendFormat(" maxCropWidth = %u, maxCropHeight = %u\n", restrictionSize.maxCropWidth,
79 restrictionSize.maxCropHeight);
80 result.appendFormat(" minCropWidth = %u, minCropHeight = %u\n", restrictionSize.minCropWidth,
81 restrictionSize.minCropHeight);
82 result.appendFormat(" cropXAlign = %u, cropYAlign = %u\n", restrictionSize.cropXAlign,
83 restrictionSize.cropYAlign);
84 result.appendFormat(" cropWidthAlign = %u, cropHeightAlign = %u\n",
85 restrictionSize.cropWidthAlign, restrictionSize.cropHeightAlign);
86 }
87
ExynosMPPSource()88 ExynosMPPSource::ExynosMPPSource()
89 : mSourceType(MPP_SOURCE_MAX),
90 mSource(NULL),
91 mOtfMPP(NULL),
92 mM2mMPP(NULL)
93 {
94 memset(&mSrcImg, 0, sizeof(mSrcImg));
95 mSrcImg.acquireFenceFd = -1;
96 mSrcImg.releaseFenceFd = -1;
97 memset(&mDstImg, 0, sizeof(mDstImg));
98 mDstImg.acquireFenceFd = -1;
99 mDstImg.releaseFenceFd = -1;
100 memset(&mMidImg, 0, sizeof(mMidImg));
101 mMidImg.acquireFenceFd = -1;
102 mMidImg.releaseFenceFd = -1;
103 }
104
ExynosMPPSource(uint32_t sourceType,void * source)105 ExynosMPPSource::ExynosMPPSource(uint32_t sourceType, void *source)
106 : mSourceType(sourceType),
107 mSource(source),
108 mOtfMPP(NULL),
109 mM2mMPP(NULL)
110 {
111 memset(&mSrcImg, 0, sizeof(mSrcImg));
112 mSrcImg.acquireFenceFd = -1;
113 mSrcImg.releaseFenceFd = -1;
114 memset(&mDstImg, 0, sizeof(mDstImg));
115 mDstImg.acquireFenceFd = -1;
116 mDstImg.releaseFenceFd = -1;
117 memset(&mMidImg, 0, sizeof(mMidImg));
118 mMidImg.acquireFenceFd = -1;
119 mMidImg.releaseFenceFd = -1;
120 }
121
setExynosImage(exynos_image src_img,exynos_image dst_img)122 void ExynosMPPSource::setExynosImage(exynos_image src_img, exynos_image dst_img)
123 {
124 mSrcImg = src_img;
125 mDstImg = dst_img;
126 }
127
setExynosMidImage(exynos_image mid_img)128 void ExynosMPPSource::setExynosMidImage(exynos_image mid_img)
129 {
130 mMidImg = mid_img;
131 }
132
ExynosMPP(ExynosResourceManager * resourceManager,uint32_t physicalType,uint32_t logicalType,const char * name,uint32_t physicalIndex,uint32_t logicalIndex,uint32_t preAssignInfo)133 ExynosMPP::ExynosMPP(ExynosResourceManager* resourceManager,
134 uint32_t physicalType, uint32_t logicalType, const char *name,
135 uint32_t physicalIndex, uint32_t logicalIndex, uint32_t preAssignInfo)
136 : mResourceManager(resourceManager),
137 mMPPType(MPP_TYPE_NONE),
138 mPhysicalType(physicalType),
139 mLogicalType(logicalType),
140 mName(name),
141 mPhysicalIndex(physicalIndex),
142 mLogicalIndex(logicalIndex),
143 mPreAssignDisplayInfo(preAssignInfo),
144 mHWState(MPP_HW_STATE_IDLE),
145 mLastStateFenceFd(-1),
146 mAssignedState(MPP_ASSIGN_STATE_FREE),
147 mEnable(true),
148 mAssignedDisplay(NULL),
149 mMaxSrcLayerNum(1),
150 mPrevAssignedState(MPP_ASSIGN_STATE_FREE),
151 mPrevAssignedDisplayType(-1),
152 mReservedDisplay(-1),
153 mResourceManageThread(android::sp<ResourceManageThread>::make(this)),
154 mCapacity(-1),
155 mUsedCapacity(0),
156 mAllocOutBufFlag(true),
157 mFreeOutBufFlag(true),
158 mHWBusyFlag(false),
159 mCurrentDstBuf(0),
160 mPrivDstBuf(-1),
161 mNeedCompressedTarget(false),
162 mDstAllocatedSize(DST_SIZE_UNKNOWN),
163 mUseM2MSrcFence(false),
164 mAttr(0),
165 mNeedSolidColorLayer(false)
166 {
167 if (mPhysicalType < MPP_DPP_NUM) {
168 mClockKhz = VPP_CLOCK;
169 mPPC = VPP_PIXEL_PER_CLOCK;
170 }
171
172 if (mPhysicalType == MPP_G2D) {
173 mClockKhz = G2D_CLOCK;
174 if (mLogicalType == MPP_LOGICAL_G2D_RGB) {
175
176 char value[256];
177 int afbc_prop;
178 property_get("ro.vendor.ddk.set.afbc", value, "0");
179 afbc_prop = atoi(value);
180 if (afbc_prop == 0)
181 mNeedCompressedTarget = false;
182 else
183 mNeedCompressedTarget = true;
184
185 mMaxSrcLayerNum = G2D_MAX_SRC_NUM;
186 } else if (mLogicalType == MPP_LOGICAL_G2D_COMBO &&
187 (mPreAssignDisplayInfo & HWC_DISPLAY_VIRTUAL_BIT)) {
188 mMaxSrcLayerNum = G2D_MAX_SRC_NUM - 1;
189 mAllocOutBufFlag = false;
190 mNeedCompressedTarget = false;
191 mUseM2MSrcFence = true;
192 }
193 /* Capacity means time(ms) that can be used for operation */
194 mCapacity = MPP_G2D_CAPACITY;
195 mAcrylicHandle = AcrylicFactory::createAcrylic("default_compositor");
196 if (mAcrylicHandle == NULL) {
197 MPP_LOGE("Fail to allocate acrylic handle");
198 abort();
199 } else {
200 MPP_LOGI("mAcrylicHandle is created: %p", mAcrylicHandle);
201 }
202 }
203
204 /* Basic feature supported flags */
205 for (const auto &feature: feature_table) {
206 if (feature.hwType == mPhysicalType)
207 mAttr = feature.attr;
208 }
209
210 if (mPhysicalType == MPP_MSC) {
211 mClockKhz = MSC_CLOCK;
212 /* To do
213 * Capacity should be set
214 */
215 mCapacity = MPP_MSC_CAPACITY;
216 mAcrylicHandle = AcrylicFactory::createAcrylic("default_scaler");
217 if (mAcrylicHandle == NULL) {
218 MPP_LOGE("Fail to allocate acrylic handle");
219 abort();
220 } else {
221 MPP_LOGI("mAcrylicHandle is created: %p", mAcrylicHandle);
222 }
223 }
224
225 if (mMaxSrcLayerNum > 1) {
226 mNeedSolidColorLayer = true;
227 mAcrylicHandle->setDefaultColor(0, 0, 0, 0);
228 }
229
230 mAssignedSources.clear();
231 resetUsedCapacity();
232
233 mResourceManageThread->mRunning = true;
234 mResourceManageThread->run("MPPThread");
235
236 memset(&mPrevFrameInfo, 0, sizeof(mPrevFrameInfo));
237 for (int i = 0; i < NUM_MPP_SRC_BUFS; i++) {
238 mPrevFrameInfo.srcInfo[i].acquireFenceFd = -1;
239 mPrevFrameInfo.srcInfo[i].releaseFenceFd = -1;
240 mPrevFrameInfo.dstInfo[i].acquireFenceFd = -1;
241 mPrevFrameInfo.dstInfo[i].releaseFenceFd = -1;
242 }
243
244 for (uint32_t i = 0; i < NUM_MPP_SRC_BUFS; i++) {
245 memset(&mSrcImgs[i], 0, sizeof(mSrcImgs[i]));
246 mSrcImgs[i].acrylicAcquireFenceFd = -1;
247 mSrcImgs[i].acrylicReleaseFenceFd = -1;
248 }
249 for (uint32_t i = 0; i < NUM_MPP_DST_BUFS(mLogicalType); i++) {
250 memset(&mDstImgs[i], 0, sizeof(mDstImgs[i]));
251 mDstImgs[i].acrylicAcquireFenceFd = -1;
252 mDstImgs[i].acrylicReleaseFenceFd = -1;
253 }
254
255 for (uint32_t i = 0; i < DISPLAY_MODE_NUM; i++)
256 {
257 mPreAssignDisplayList[i] = (preAssignInfo >> (DISPLAY_MODE_MASK_LEN * i)) & DISPLAY_MODE_MASK_BIT;
258 }
259 }
260
~ExynosMPP()261 ExynosMPP::~ExynosMPP()
262 {
263 mResourceManageThread->mRunning = false;
264 mResourceManageThread->requestExitAndWait();
265 }
266
267
ResourceManageThread(ExynosMPP * exynosMPP)268 ExynosMPP::ResourceManageThread::ResourceManageThread(ExynosMPP *exynosMPP)
269 : mExynosMPP(exynosMPP),
270 mRunning(false)
271 {
272 }
273
~ResourceManageThread()274 ExynosMPP::ResourceManageThread::~ResourceManageThread()
275 {
276 }
277
isDataspaceSupportedByMPP(struct exynos_image & src,struct exynos_image & dst)278 bool ExynosMPP::isDataspaceSupportedByMPP(struct exynos_image &src, struct exynos_image &dst)
279 {
280 uint32_t srcStandard = (src.dataSpace & HAL_DATASPACE_STANDARD_MASK);
281 uint32_t dstStandard = (dst.dataSpace & HAL_DATASPACE_STANDARD_MASK);
282 uint32_t srcTransfer = (src.dataSpace & HAL_DATASPACE_TRANSFER_MASK);
283 uint32_t dstTransfer = (dst.dataSpace & HAL_DATASPACE_TRANSFER_MASK);
284
285 /* No conversion case */
286 if ((srcStandard == dstStandard) && (srcTransfer == dstTransfer))
287 return true;
288
289 /* Unspecified conversion case */
290 if (((srcStandard == HAL_DATASPACE_STANDARD_UNSPECIFIED) ||
291 (dstStandard == HAL_DATASPACE_STANDARD_UNSPECIFIED)) &&
292 ((srcTransfer == HAL_DATASPACE_TRANSFER_UNSPECIFIED) ||
293 (dstTransfer == HAL_DATASPACE_TRANSFER_UNSPECIFIED)))
294 return true;
295
296 /* WCG support check */
297 /* 'Src is not HDR' and 'src,dst has differenct dataspace' means WCG case */
298 /* Some MPPs are only support HDR but WCG */
299 if (!hasHdrInfo(src) && ((mAttr & MPP_ATTR_WCG) == 0))
300 return false;
301
302 /* Standard support check */
303 auto standard_it = dataspace_standard_map.find(srcStandard);
304 if ((standard_it == dataspace_standard_map.end()) ||
305 ((mAttr & standard_it->second) == 0))
306 return false;
307
308 /* Transfer support check */
309 auto transfer_it = dataspace_transfer_map.find(srcTransfer);
310 if ((transfer_it == dataspace_transfer_map.end()) ||
311 ((mAttr & transfer_it->second) == 0))
312 return false;
313
314 return checkCSCRestriction(src, dst);
315 }
316
isSupportedHDR10Plus(struct exynos_image & src,struct exynos_image & dst)317 bool ExynosMPP::isSupportedHDR10Plus(struct exynos_image &src, struct exynos_image &dst)
318 {
319
320 uint32_t srcStandard = (src.dataSpace & HAL_DATASPACE_STANDARD_MASK);
321 uint32_t dstStandard = (dst.dataSpace & HAL_DATASPACE_STANDARD_MASK);
322 uint32_t srcTransfer = (src.dataSpace & HAL_DATASPACE_TRANSFER_MASK);
323 uint32_t dstTransfer = (dst.dataSpace & HAL_DATASPACE_TRANSFER_MASK);
324
325 if (hasHdr10Plus(src)) {
326 if (mAttr & MPP_ATTR_HDR10PLUS)
327 return true;
328 else if ((srcStandard == dstStandard) && (srcTransfer == dstTransfer))
329 return true;
330 else if ((mLogicalType == MPP_LOGICAL_G2D_COMBO) && (mPreAssignDisplayInfo & HWC_DISPLAY_VIRTUAL_BIT))
331 return true;
332 else
333 return false;
334 }
335 return true;
336 }
337
isSupportedHStrideCrop(struct exynos_image __unused & src)338 bool ExynosMPP::isSupportedHStrideCrop(struct exynos_image __unused &src)
339 {
340 return true;
341 }
342
isSupportedBlend(struct exynos_image & src)343 bool ExynosMPP::isSupportedBlend(struct exynos_image &src)
344 {
345 switch(src.blending) {
346 case HWC2_BLEND_MODE_NONE:
347 case HWC2_BLEND_MODE_PREMULTIPLIED:
348 case HWC2_BLEND_MODE_COVERAGE:
349 return true;
350 default:
351 return false;
352 }
353 }
354
checkRotationCondition(struct exynos_image & src)355 bool ExynosMPP::checkRotationCondition(struct exynos_image &src)
356 {
357 /* Check only DPP types */
358 if (mPhysicalType >= MPP_DPP_NUM)
359 return true;
360
361 /* If DPP has their own restriction, implmemnt module codes */
362 if (mAttr & MPP_ATTR_ROT_90) {
363 if (isFormatYUV420(src.format) == true)
364 return true;
365 }
366
367 /* Other DPPs */
368 if ((src.transform & HAL_TRANSFORM_ROT_90) == 0)
369 {
370 if ((src.compressed == 1) && (src.transform != 0))
371 return false;
372 return true;
373 } else {
374 return false;
375 }
376
377 return true;
378 }
379
isSupportedTransform(struct exynos_image & src)380 bool ExynosMPP::isSupportedTransform(struct exynos_image &src)
381 {
382 if (src.transform == 0) return true;
383
384 /* If MPP need to check additional condition,
385 * implement checkRotationCondition function to check it */
386 /* For example, DPP need to check custom conditons */
387 if (!checkRotationCondition(src))
388 return false;
389
390 for(auto transform_map : transform_map_table) {
391 if (src.transform & transform_map.hal_tr) {
392 if (!(mAttr & transform_map.hwc_tr))
393 return false;
394 }
395 }
396
397 return true;
398 }
399
isSupportedCompression(struct exynos_image & src)400 bool ExynosMPP::isSupportedCompression(struct exynos_image &src)
401 {
402 if (src.compressed) {
403 if (mAttr & MPP_ATTR_AFBC)
404 return true;
405 else
406 return false;
407 } else {
408 return true;
409 }
410 }
411
isSupportedCapability(ExynosDisplay & display,struct exynos_image & src)412 bool ExynosMPP::isSupportedCapability(ExynosDisplay &display, struct exynos_image &src)
413 {
414 if (display.mType != HWC_DISPLAY_EXTERNAL)
415 return true;
416
417 if (!(mAttr & MPP_ATTR_USE_CAPA))
418 return true;
419
420 if (mResourceManager->hasHdrLayer || mResourceManager->hasDrmLayer) {
421 if (getDrmMode(src.usageFlags) != NO_DRM)
422 return true;
423 else if (hasHdrInfo(src))
424 return true;
425 else
426 return false;
427 }
428
429 return true;
430 }
431
isSupportedDRM(struct exynos_image & src)432 bool ExynosMPP::isSupportedDRM(struct exynos_image &src)
433 {
434 if (getDrmMode(src.usageFlags) == NO_DRM)
435 return true;
436
437 if (mLogicalType == MPP_LOGICAL_G2D_RGB)
438 return false;
439
440 return true;
441 }
442
checkCSCRestriction(struct exynos_image & src,struct exynos_image & dst)443 bool ExynosMPP::checkCSCRestriction(struct exynos_image &src, struct exynos_image &dst)
444 {
445 return true;
446 }
447
isDimLayerSupported()448 bool ExynosMPP::isDimLayerSupported()
449 {
450 if (mAttr & MPP_ATTR_DIM)
451 return true;
452
453 return false;
454 }
455
isSrcFormatSupported(struct exynos_image & src)456 bool ExynosMPP::isSrcFormatSupported(struct exynos_image &src)
457 {
458 if (mLogicalType == MPP_LOGICAL_G2D_YUV) {
459 /* Support YUV layer and HDR RGB layer */
460 if (isFormatRgb(src.format) && (hasHdrInfo(src) == false))
461 return false;
462 }
463 if ((mLogicalType == MPP_LOGICAL_G2D_RGB) &&
464 isFormatYUV(src.format))
465 return false;
466 if ((mLogicalType == MPP_LOGICAL_MSC_YUV) &&
467 isFormatRgb(src.format)) {
468 return false;
469 }
470
471 if (mResourceManager == NULL) return false;
472
473 for (uint32_t i = 0 ; i < mResourceManager->mFormatRestrictionCnt; i++) {
474 if ((mResourceManager->mFormatRestrictions[i].hwType == mPhysicalType) &&
475 ((mResourceManager->mFormatRestrictions[i].nodeType == NODE_NONE) ||
476 (mResourceManager->mFormatRestrictions[i].nodeType == NODE_SRC)) &&
477 (mResourceManager->mFormatRestrictions[i].format == src.format))
478 return true;
479 }
480
481 return false;
482 }
483
isDstFormatSupported(struct exynos_image & dst)484 bool ExynosMPP::isDstFormatSupported(struct exynos_image &dst)
485 {
486
487 for (uint32_t i = 0 ; i < mResourceManager->mFormatRestrictionCnt; i++) {
488 if ((mResourceManager->mFormatRestrictions[i].hwType == mPhysicalType) &&
489 ((mResourceManager->mFormatRestrictions[i].nodeType == NODE_NONE) ||
490 (mResourceManager->mFormatRestrictions[i].nodeType == NODE_DST)) &&
491 (mResourceManager->mFormatRestrictions[i].format == dst.format))
492 return true;
493 }
494
495 return false;
496 }
497
getMaxUpscale(const struct exynos_image & src,const struct exynos_image __unused & dst) const498 uint32_t ExynosMPP::getMaxUpscale(const struct exynos_image &src,
499 const struct exynos_image __unused &dst) const {
500 uint32_t idx = getRestrictionClassification(src);
501 return mSrcSizeRestrictions[idx].maxUpScale;
502 }
503
checkDownscaleCap(const float resolution,const float displayRatio_V) const504 bool ExynosMPP::checkDownscaleCap(const float resolution, const float displayRatio_V) const {
505 if (mPhysicalType >= MPP_DPP_NUM) return true;
506
507 return float(mClockKhz) >= ((resolution * VPP_RESOL_MARGIN) / (mPPC * displayRatio_V));
508 }
509
getDownscaleRestriction(const struct exynos_image & src,const struct exynos_image &) const510 uint32_t ExynosMPP::getDownscaleRestriction(const struct exynos_image &src,
511 const struct exynos_image & /*dst*/) const {
512 auto idx = getRestrictionClassification(src);
513 return mDstSizeRestrictions[idx].maxDownScale;
514 }
515
getMaxDownscale(const ExynosDisplay & display,const struct exynos_image & src,const struct exynos_image & dst) const516 uint32_t ExynosMPP::getMaxDownscale(const ExynosDisplay &display, const struct exynos_image &src,
517 const struct exynos_image &dst) const {
518 uint32_t maxDownscale = getDownscaleRestriction(src, dst);
519
520 if (maxDownscale <= 1) {
521 return maxDownscale;
522 }
523
524 if (mPhysicalType < MPP_DPP_NUM) {
525 float resolution = float(src.w) * float(src.h) * display.getBtsRefreshRate() / 1000;
526 if (!checkDownscaleCap(resolution, float(dst.h) / float(display.mYres))) {
527 return 1;
528 }
529 }
530
531 return maxDownscale;
532 }
533
getSrcXOffsetAlign(struct exynos_image & src)534 uint32_t ExynosMPP::getSrcXOffsetAlign(struct exynos_image &src)
535 {
536 /* Refer module(ExynosMPPModule) for chip specific restrictions */
537 uint32_t idx = getRestrictionClassification(src);
538 if ((mPhysicalType == MPP_MSC) &&
539 ((src.format == HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SPN_S10B) ||
540 (src.format == HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SP_M_S10B))) {
541 return 16;
542 }
543 return mSrcSizeRestrictions[idx].cropXAlign;
544 }
getSrcXOffsetAlign(uint32_t idx)545 uint32_t ExynosMPP::getSrcXOffsetAlign(uint32_t idx)
546 {
547 if (idx >= RESTRICTION_MAX)
548 {
549 MPP_LOGE("invalid idx: %d", idx);
550 return 16;
551 }
552 return mSrcSizeRestrictions[idx].cropXAlign;
553 }
getSrcYOffsetAlign(struct exynos_image & src)554 uint32_t ExynosMPP::getSrcYOffsetAlign(struct exynos_image &src)
555 {
556 uint32_t idx = getRestrictionClassification(src);
557 return mSrcSizeRestrictions[idx].cropYAlign;
558 }
getSrcYOffsetAlign(uint32_t idx)559 uint32_t ExynosMPP::getSrcYOffsetAlign(uint32_t idx)
560 {
561 if (idx >= RESTRICTION_MAX)
562 {
563 MPP_LOGE("invalid idx: %d", idx);
564 return 16;
565 }
566 return mSrcSizeRestrictions[idx].cropYAlign;
567 }
getSrcWidthAlign(struct exynos_image & src)568 uint32_t ExynosMPP::getSrcWidthAlign(struct exynos_image &src)
569 {
570 uint32_t idx = getRestrictionClassification(src);
571 return mSrcSizeRestrictions[idx].fullWidthAlign;
572 }
getSrcHeightAlign(struct exynos_image & src)573 uint32_t ExynosMPP::getSrcHeightAlign(struct exynos_image &src)
574 {
575 uint32_t idx = getRestrictionClassification(src);
576 return mSrcSizeRestrictions[idx].fullHeightAlign;
577 }
getSrcMaxWidth(struct exynos_image & src)578 uint32_t ExynosMPP::getSrcMaxWidth(struct exynos_image &src)
579 {
580 if (isFormatYUV(src.format))
581 return 4096;
582
583 uint32_t idx = getRestrictionClassification(src);
584 return mSrcSizeRestrictions[idx].maxFullWidth;
585 }
getSrcMaxHeight(struct exynos_image & src)586 uint32_t ExynosMPP::getSrcMaxHeight(struct exynos_image &src)
587 {
588 if (isFormatYUV(src.format))
589 return 4096;
590
591 uint32_t idx = getRestrictionClassification(src);
592 return mSrcSizeRestrictions[idx].maxFullHeight;
593 }
getSrcMinWidth(struct exynos_image & src)594 uint32_t ExynosMPP::getSrcMinWidth(struct exynos_image &src)
595 {
596 uint32_t idx = getRestrictionClassification(src);
597 return mSrcSizeRestrictions[idx].minFullWidth;
598 }
getSrcMinWidth(uint32_t idx)599 uint32_t ExynosMPP::getSrcMinWidth(uint32_t idx)
600 {
601 if (idx >= RESTRICTION_MAX)
602 {
603 MPP_LOGE("invalid idx: %d", idx);
604 return 16;
605 }
606 return mSrcSizeRestrictions[idx].minFullWidth;
607 }
getSrcMinHeight(struct exynos_image & src)608 uint32_t ExynosMPP::getSrcMinHeight(struct exynos_image &src)
609 {
610 uint32_t idx = getRestrictionClassification(src);
611 return mSrcSizeRestrictions[idx].minFullHeight;
612 }
getSrcMinHeight(uint32_t idx)613 uint32_t ExynosMPP::getSrcMinHeight(uint32_t idx)
614 {
615 if (idx >= RESTRICTION_MAX)
616 {
617 MPP_LOGE("invalid idx: %d", idx);
618 return 16;
619 }
620 return mSrcSizeRestrictions[idx].minFullHeight;
621 }
getSrcMaxCropWidth(struct exynos_image & src)622 uint32_t ExynosMPP::getSrcMaxCropWidth(struct exynos_image &src)
623 {
624 uint32_t idx = getRestrictionClassification(src);
625 return mSrcSizeRestrictions[idx].maxCropWidth;
626 }
getSrcMaxCropHeight(struct exynos_image & src)627 uint32_t ExynosMPP::getSrcMaxCropHeight(struct exynos_image &src)
628 {
629 if ((mMPPType == MPP_TYPE_OTF) &&
630 (src.transform & HAL_TRANSFORM_ROT_90))
631 return 2160;
632
633 uint32_t idx = getRestrictionClassification(src);
634 return mSrcSizeRestrictions[idx].maxCropHeight;
635 }
getSrcMaxCropSize(struct exynos_image & src)636 uint32_t ExynosMPP::getSrcMaxCropSize(struct exynos_image &src)
637 {
638 return (getSrcMaxCropWidth(src) * getSrcMaxCropHeight(src));
639 }
getSrcMinCropWidth(struct exynos_image & src)640 uint32_t ExynosMPP::getSrcMinCropWidth(struct exynos_image &src)
641 {
642 if (((src.format == HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SPN_S10B) ||
643 (src.format == HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SP_M_S10B)) &&
644 (mPhysicalType == MPP_G2D))
645 return 2;
646 uint32_t idx = getRestrictionClassification(src);
647 return mSrcSizeRestrictions[idx].minCropWidth;
648 }
getSrcMinCropHeight(struct exynos_image & src)649 uint32_t ExynosMPP::getSrcMinCropHeight(struct exynos_image &src)
650 {
651 if (((src.format == HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SPN_S10B) ||
652 (src.format == HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SP_M_S10B)) &&
653 (mPhysicalType == MPP_G2D))
654 return 2;
655 uint32_t idx = getRestrictionClassification(src);
656 return mSrcSizeRestrictions[idx].minCropHeight;
657 }
getSrcCropWidthAlign(const struct exynos_image & src) const658 uint32_t ExynosMPP::getSrcCropWidthAlign(const struct exynos_image &src) const {
659 if (((src.format == HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SPN_S10B) ||
660 (src.format == HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SP_M_S10B)) &&
661 (mPhysicalType == MPP_G2D))
662 return 2;
663 uint32_t idx = getRestrictionClassification(src);
664 return mSrcSizeRestrictions[idx].cropWidthAlign;
665 }
666
667 /* This is used for only otfMPP */
getSrcCropWidthAlign(uint32_t idx) const668 uint32_t ExynosMPP::getSrcCropWidthAlign(uint32_t idx) const {
669 if (idx >= RESTRICTION_MAX)
670 {
671 MPP_LOGE("invalid idx: %d", idx);
672 return 16;
673 }
674 return mSrcSizeRestrictions[idx].cropWidthAlign;
675 }
getSrcCropHeightAlign(const struct exynos_image & src) const676 uint32_t ExynosMPP::getSrcCropHeightAlign(const struct exynos_image &src) const {
677 if (((src.format == HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SPN_S10B) ||
678 (src.format == HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SP_M_S10B)) &&
679 (mPhysicalType == MPP_G2D))
680 return 2;
681
682 uint32_t idx = getRestrictionClassification(src);
683 return mSrcSizeRestrictions[idx].cropHeightAlign;
684 }
685
686 /* This is used for only otfMPP */
getSrcCropHeightAlign(uint32_t idx) const687 uint32_t ExynosMPP::getSrcCropHeightAlign(uint32_t idx) const {
688 if (idx >= RESTRICTION_MAX)
689 {
690 MPP_LOGE("invalid idx: %d", idx);
691 return 16;
692 }
693 return mSrcSizeRestrictions[idx].cropHeightAlign;
694 }
getDstMaxWidth(struct exynos_image & dst)695 uint32_t ExynosMPP::getDstMaxWidth(struct exynos_image &dst)
696 {
697 uint32_t idx = getRestrictionClassification(dst);
698 return mDstSizeRestrictions[idx].maxCropWidth;
699 }
getDstMaxHeight(struct exynos_image & dst)700 uint32_t ExynosMPP::getDstMaxHeight(struct exynos_image &dst)
701 {
702 uint32_t idx = getRestrictionClassification(dst);
703 return mDstSizeRestrictions[idx].maxCropHeight;
704 }
getDstMinWidth(struct exynos_image & dst)705 uint32_t ExynosMPP::getDstMinWidth(struct exynos_image &dst)
706 {
707 if (((dst.format == HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SPN_S10B) ||
708 (dst.format == HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SP_M_S10B)) &&
709 (mPhysicalType == MPP_G2D))
710 return 64;
711
712 if ((mNeedSolidColorLayer == false) && mNeedCompressedTarget)
713 return 16;
714
715 if ((mPhysicalType == MPP_G2D) && (mNeedSolidColorLayer == false) &&
716 isFormatSBWC(dst.format))
717 return 32;
718
719 uint32_t idx = getRestrictionClassification(dst);
720 return mDstSizeRestrictions[idx].minCropWidth;
721 }
getDstMinHeight(struct exynos_image & dst)722 uint32_t ExynosMPP::getDstMinHeight(struct exynos_image &dst)
723 {
724 if ((mNeedSolidColorLayer == false) && mNeedCompressedTarget)
725 return 16;
726
727 if ((mPhysicalType == MPP_G2D) && (mNeedSolidColorLayer == false) &&
728 isFormatSBWC(dst.format))
729 return 8;
730
731 uint32_t idx = getRestrictionClassification(dst);
732 return mDstSizeRestrictions[idx].minCropHeight;
733 }
getDstWidthAlign(const struct exynos_image & dst) const734 uint32_t ExynosMPP::getDstWidthAlign(const struct exynos_image &dst) const {
735 if (((dst.format == HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SPN_S10B) ||
736 (dst.format == HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SP_M_S10B)) &&
737 (mPhysicalType == MPP_G2D))
738 return 64;
739
740 if ((mNeedSolidColorLayer == false) && mNeedCompressedTarget)
741 return 16;
742
743 if ((mPhysicalType == MPP_G2D) && (mNeedSolidColorLayer == false) &&
744 isFormatSBWC(dst.format))
745 return 32;
746
747 uint32_t idx = getRestrictionClassification(dst);
748 return mDstSizeRestrictions[idx].cropWidthAlign;
749 }
getDstHeightAlign(const struct exynos_image & dst) const750 uint32_t ExynosMPP::getDstHeightAlign(const struct exynos_image &dst) const {
751 if ((mNeedSolidColorLayer == false) && mNeedCompressedTarget)
752 return 16;
753
754 if ((mPhysicalType == MPP_G2D) && (mNeedSolidColorLayer == false) &&
755 isFormatSBWC(dst.format))
756 return 8;
757
758 uint32_t idx = getRestrictionClassification(dst);
759 return mDstSizeRestrictions[idx].cropHeightAlign;
760 }
getDstXOffsetAlign(struct exynos_image & dst)761 uint32_t ExynosMPP::getDstXOffsetAlign(struct exynos_image &dst)
762 {
763 if ((mNeedSolidColorLayer == false) && mNeedCompressedTarget)
764 return 16;
765
766 if ((mPhysicalType == MPP_G2D) && (mNeedSolidColorLayer == false) &&
767 isFormatSBWC(dst.format))
768 return 32;
769
770 uint32_t idx = getRestrictionClassification(dst);
771 return mDstSizeRestrictions[idx].cropXAlign;
772 }
getDstYOffsetAlign(struct exynos_image & dst)773 uint32_t ExynosMPP::getDstYOffsetAlign(struct exynos_image &dst)
774 {
775 if ((mNeedSolidColorLayer == false) && mNeedCompressedTarget)
776 return 16;
777
778 if ((mPhysicalType == MPP_G2D) && (mNeedSolidColorLayer == false) &&
779 isFormatSBWC(dst.format))
780 return 8;
781
782 uint32_t idx = getRestrictionClassification(dst);
783 return mDstSizeRestrictions[idx].cropYAlign;
784 }
getOutBufAlign()785 uint32_t ExynosMPP::getOutBufAlign()
786 {
787 if (mNeedCompressedTarget)
788 return 16;
789 else
790 return 1;
791 }
792
isSupportLayerColorTransform(struct exynos_image & src,struct exynos_image __unused & dst)793 int32_t ExynosMPP::isSupportLayerColorTransform(
794 struct exynos_image &src, struct exynos_image __unused &dst)
795 {
796 if (src.needColorTransform == false)
797 return true;
798
799 if (mAttr & MPP_ATTR_LAYER_TRANSFORM)
800 return true;
801
802 return false;
803 }
804
threadLoop()805 bool ExynosMPP::ResourceManageThread::threadLoop()
806 {
807 if (mExynosMPP == NULL)
808 return false;
809
810 ALOGI("%s threadLoop is started", mExynosMPP->mName.string());
811 while(mRunning) {
812 Mutex::Autolock lock(mMutex);
813 while((mFreedBuffers.size() == 0) &&
814 (mStateFences.size() == 0)) {
815 mCondition.wait(mMutex);
816 }
817
818 if ((mExynosMPP->mHWState == MPP_HW_STATE_RUNNING) &&
819 (mStateFences.size() != 0)) {
820 if (checkStateFences()) {
821 mExynosMPP->mHWState = MPP_HW_STATE_IDLE;
822 }
823 } else {
824 if ((mStateFences.size() != 0) &&
825 (mExynosMPP->mHWState != MPP_HW_STATE_RUNNING)) {
826 ALOGW("%s, mHWState(%d) but mStateFences size(%zu)",
827 mExynosMPP->mName.string(), mExynosMPP->mHWState,
828 mStateFences.size());
829 checkStateFences();
830 }
831 }
832
833 if (mFreedBuffers.size() != 0) {
834 freeBuffers();
835 }
836 }
837 return true;
838 }
839
freeBuffers()840 void ExynosMPP::ResourceManageThread::freeBuffers()
841 {
842 VendorGraphicBufferAllocator& gAllocator(VendorGraphicBufferAllocator::get());
843 android::List<exynos_mpp_img_info >::iterator it;
844 android::List<exynos_mpp_img_info >::iterator end;
845 it = mFreedBuffers.begin();
846 end = mFreedBuffers.end();
847
848 uint32_t freebufNum = 0;
849 while (it != end) {
850 exynos_mpp_img_info freeBuffer = (exynos_mpp_img_info)(*it);
851 HDEBUGLOGD(eDebugMPP|eDebugFence|eDebugBuf, "freebufNum: %d, buffer: %p", freebufNum, freeBuffer.bufferHandle);
852 dumpExynosMPPImgInfo(eDebugMPP|eDebugFence|eDebugBuf, freeBuffer);
853 if (fence_valid(freeBuffer.acrylicAcquireFenceFd)) {
854 if (sync_wait(freeBuffer.acrylicAcquireFenceFd, 1000) < 0)
855 HWC_LOGE(NULL, "%s:: acquire fence sync_wait error", mExynosMPP->mName.string());
856 freeBuffer.acrylicAcquireFenceFd =
857 fence_close(freeBuffer.acrylicAcquireFenceFd, mExynosMPP->mAssignedDisplay,
858 FENCE_TYPE_SRC_ACQUIRE, FENCE_IP_ALL);
859 }
860 if (fence_valid(freeBuffer.acrylicReleaseFenceFd)) {
861 if (sync_wait(freeBuffer.acrylicReleaseFenceFd, 1000) < 0)
862 HWC_LOGE(NULL, "%s:: release fence sync_wait error", mExynosMPP->mName.string());
863 freeBuffer.acrylicReleaseFenceFd =
864 fence_close(freeBuffer.acrylicReleaseFenceFd, mExynosMPP->mAssignedDisplay,
865 FENCE_TYPE_SRC_RELEASE, FENCE_IP_ALL);
866 }
867 gAllocator.free(freeBuffer.bufferHandle);
868 it = mFreedBuffers.erase(it);
869 }
870 }
871
checkStateFences()872 bool ExynosMPP::ResourceManageThread::checkStateFences()
873 {
874 bool ret = true;
875 android::List<int >::iterator it;
876 android::List<int >::iterator end;
877
878 it = mStateFences.begin();
879 end = mStateFences.end();
880 uint32_t waitFenceNum = 0;
881 while (it != end) {
882 int fence = (int)(*it);
883 HDEBUGLOGD(eDebugMPP|eDebugFence, "%d wait fence: %d", waitFenceNum, fence);
884 waitFenceNum++;
885 if (fence_valid(fence)) {
886 if (sync_wait(fence, 5000) < 0) {
887 HWC_LOGE(NULL, "%s::[%s][%d] sync_wait(%d) error(%s)", __func__,
888 mExynosMPP->mName.string(), mExynosMPP->mLogicalIndex, fence, strerror(errno));
889 ret = false;
890 }
891 fence = fence_close(fence, mExynosMPP->mAssignedDisplay,
892 FENCE_TYPE_ALL, FENCE_IP_ALL);
893 }
894 it = mStateFences.erase(it);
895 }
896 return ret;
897 }
898
addFreedBuffer(exynos_mpp_img_info freedBuffer)899 void ExynosMPP::ResourceManageThread::addFreedBuffer(exynos_mpp_img_info freedBuffer)
900 {
901 android::Mutex::Autolock lock(mMutex);
902 mFreedBuffers.push_back(freedBuffer);
903 mCondition.signal();
904 }
905
addStateFence(int fence)906 void ExynosMPP::ResourceManageThread::addStateFence(int fence)
907 {
908 Mutex::Autolock lock(mMutex);
909 HDEBUGLOGD(eDebugMPP|eDebugFence, "wait fence is added: %d", fence);
910 mStateFences.push_back(fence);
911 mCondition.signal();
912 }
913
914 /**
915 * @param w
916 * @param h
917 * @param color
918 * @param usage
919 * @return int32_t
920 */
allocOutBuf(uint32_t w,uint32_t h,uint32_t format,uint64_t usage,uint32_t index)921 int32_t ExynosMPP::allocOutBuf(uint32_t w, uint32_t h, uint32_t format, uint64_t usage, uint32_t index) {
922 ATRACE_CALL();
923 uint32_t dstStride = 0;
924
925 MPP_LOGD(eDebugMPP|eDebugBuf, "index: %d++++++++", index);
926
927 if (index >= NUM_MPP_DST_BUFS(mLogicalType)) {
928 return -EINVAL;
929 }
930
931 exynos_mpp_img_info freeDstBuf = mDstImgs[index];
932 MPP_LOGD(eDebugMPP|eDebugBuf, "mDstImg[%d] is reallocated", index);
933 dumpExynosMPPImgInfo(eDebugMPP, mDstImgs[index]);
934
935 uint64_t allocUsage = getBufferUsage(usage);
936 if (!needCompressDstBuf()) {
937 allocUsage |= VendorGraphicBufferUsage::NO_AFBC;
938 }
939 buffer_handle_t dstBuffer;
940
941 MPP_LOGD(eDebugMPP|eDebugBuf, "\tw: %d, h: %d, format: 0x%8x, previousBuffer: %p, allocUsage: 0x%" PRIx64 ", usage: 0x%" PRIx64 "",
942 w, h, format, freeDstBuf.bufferHandle, allocUsage, usage);
943
944 status_t error = NO_ERROR;
945
946 {
947 ATRACE_CALL();
948
949 VendorGraphicBufferAllocator& gAllocator(VendorGraphicBufferAllocator::get());
950 error = gAllocator.allocate(w, h, format, 1, allocUsage, &dstBuffer, &dstStride, "HWC");
951 }
952
953 if ((error != NO_ERROR) || (dstBuffer == NULL)) {
954 MPP_LOGE("failed to allocate destination buffer(%dx%d): %d", w, h, error);
955 return -EINVAL;
956 }
957
958 memset(&mDstImgs[index], 0, sizeof(mDstImgs[index]));
959
960 mDstImgs[index].acrylicAcquireFenceFd = -1;
961 mDstImgs[index].acrylicReleaseFenceFd = -1;
962 mDstImgs[index].bufferHandle = dstBuffer;
963 mDstImgs[index].bufferType = getBufferType(usage);
964 mDstImgs[index].format = format;
965
966 MPP_LOGD(eDebugMPP|eDebugBuf, "free outbuf[%d] %p", index, freeDstBuf.bufferHandle);
967 if (freeDstBuf.bufferHandle != NULL)
968 freeOutBuf(freeDstBuf);
969 else {
970 if (mAssignedDisplay != NULL) {
971 freeDstBuf.acrylicAcquireFenceFd = fence_close(freeDstBuf.acrylicAcquireFenceFd,
972 mAssignedDisplay, FENCE_TYPE_SRC_ACQUIRE, FENCE_IP_G2D);
973 freeDstBuf.acrylicReleaseFenceFd = fence_close(freeDstBuf.acrylicReleaseFenceFd,
974 mAssignedDisplay, FENCE_TYPE_SRC_RELEASE, FENCE_IP_G2D);
975 }
976 }
977
978 MPP_LOGD(eDebugMPP|eDebugBuf, "dstBuffer(%p)-----------", dstBuffer);
979
980 return NO_ERROR;
981 }
982
983 /**
984 * @param outbuf
985 * @return int32_t
986 */
setOutBuf(buffer_handle_t outbuf,int32_t fence)987 int32_t ExynosMPP::setOutBuf(buffer_handle_t outbuf, int32_t fence) {
988 mDstImgs[mCurrentDstBuf].bufferHandle = NULL;
989 if (outbuf != NULL) {
990 mDstImgs[mCurrentDstBuf].bufferHandle = outbuf;
991 mDstImgs[mCurrentDstBuf].format =
992 VendorGraphicBufferMeta::get_format(mDstImgs[mCurrentDstBuf].bufferHandle);
993 }
994 setDstAcquireFence(fence);
995 return NO_ERROR;
996 }
997
998 /**
999 * @param dst
1000 * @return int32_t
1001 */
freeOutBuf(struct exynos_mpp_img_info dst)1002 int32_t ExynosMPP::freeOutBuf(struct exynos_mpp_img_info dst) {
1003 mResourceManageThread->addFreedBuffer(dst);
1004 dst.bufferHandle = NULL;
1005 return NO_ERROR;
1006 }
1007
getBufferType(uint64_t usage)1008 uint32_t ExynosMPP::getBufferType(uint64_t usage)
1009 {
1010 if (getDrmMode(usage) == SECURE_DRM)
1011 return MPP_BUFFER_SECURE_DRM;
1012 else if (getDrmMode(usage) == NORMAL_DRM)
1013 return MPP_BUFFER_NORMAL_DRM;
1014 else {
1015 if (exynosHWCControl.dumpMidBuf)
1016 return MPP_BUFFER_DUMP;
1017 else
1018 return MPP_BUFFER_NORMAL;
1019 }
1020 }
1021
getBufferType(const buffer_handle_t handle)1022 uint32_t ExynosMPP::getBufferType(const buffer_handle_t handle)
1023 {
1024 uint64_t usage = VendorGraphicBufferMeta::get_usage(handle);
1025
1026 return getBufferType(usage);
1027 }
1028
getBufferUsage(uint64_t usage)1029 uint64_t ExynosMPP::getBufferUsage(uint64_t usage)
1030 {
1031 uint64_t allocUsage = 0;
1032 if (getBufferType(usage) == MPP_BUFFER_DUMP) {
1033 allocUsage = BufferUsage::CPU_READ_OFTEN |
1034 BufferUsage::CPU_WRITE_OFTEN;
1035 } else {
1036 allocUsage = BufferUsage::CPU_READ_NEVER |
1037 BufferUsage::CPU_WRITE_NEVER |
1038 VendorGraphicBufferUsage::NOZEROED |
1039 BufferUsage::COMPOSER_OVERLAY;
1040 }
1041
1042 if (getDrmMode(usage) == SECURE_DRM) {
1043 allocUsage |= BufferUsage::PROTECTED;
1044 allocUsage &= ~VendorGraphicBufferUsage::PRIVATE_NONSECURE;
1045 } else if (getDrmMode(usage) == NORMAL_DRM) {
1046 allocUsage |= BufferUsage::PROTECTED;
1047 allocUsage |= VendorGraphicBufferUsage::PRIVATE_NONSECURE;
1048 }
1049
1050 return allocUsage;
1051 }
1052
needCompressDstBuf() const1053 bool ExynosMPP::needCompressDstBuf() const {
1054 return (mMaxSrcLayerNum > 1) && mNeedCompressedTarget;
1055 }
1056
needDstBufRealloc(struct exynos_image & dst,uint32_t index)1057 bool ExynosMPP::needDstBufRealloc(struct exynos_image &dst, uint32_t index)
1058 {
1059 MPP_LOGD(eDebugMPP|eDebugBuf, "index: %d++++++++", index);
1060
1061 if (index >= NUM_MPP_DST_BUFS(mLogicalType)) {
1062 MPP_LOGE("%s:: index(%d) is not valid", __func__, index);
1063 return false;
1064 }
1065 buffer_handle_t dst_handle = NULL;
1066 if (mDstImgs[index].bufferHandle != NULL)
1067 dst_handle = mDstImgs[index].bufferHandle;
1068
1069 if (dst_handle == NULL) {
1070 MPP_LOGD(eDebugMPP|eDebugBuf, "\tDstImag[%d] handle is NULL", index);
1071 return true;
1072 }
1073
1074 int32_t assignedDisplay = -1;
1075 if (mAssignedDisplay != NULL) {
1076 assignedDisplay = mAssignedDisplay->mType;
1077 } else {
1078 MPP_LOGE("%s:: mpp is not assigned", __func__);
1079 return false;
1080 }
1081
1082 VendorGraphicBufferMeta gmeta(dst_handle);
1083
1084 MPP_LOGD(eDebugMPP | eDebugBuf, "\tdst_handle(%p) afbc (%u) sbwc (%u) lossy (%u)", dst_handle,
1085 isAFBCCompressed(dst_handle), isFormatSBWC(gmeta.format), isFormatLossy(gmeta.format));
1086 MPP_LOGD(eDebugMPP | eDebugBuf,
1087 "\tAssignedDisplay[%d, %d] format[0x%8x, 0x%8x], bufferType[%d, %d], usageFlags: "
1088 "0x%" PRIx64 ", need afbc %u sbwc %u lossy %u",
1089 mPrevAssignedDisplayType, assignedDisplay, gmeta.format, dst.format,
1090 mDstImgs[index].bufferType, getBufferType(dst.usageFlags), dst.usageFlags,
1091 dst.compressed, isFormatSBWC(dst.format), isFormatLossy(dst.format));
1092
1093 bool realloc = (mPrevAssignedDisplayType != assignedDisplay) ||
1094 (formatToBpp(gmeta.format) < formatToBpp(dst.format)) ||
1095 ((gmeta.stride * gmeta.vstride) < (int)(dst.fullWidth * dst.fullHeight)) ||
1096 (mDstImgs[index].bufferType != getBufferType(dst.usageFlags)) ||
1097 (isAFBCCompressed(dst_handle) != dst.compressed) ||
1098 (isFormatSBWC(gmeta.format) != isFormatSBWC(dst.format)) ||
1099 (isFormatLossy(gmeta.format) != isFormatLossy(dst.format));
1100
1101 MPP_LOGD(eDebugMPP|eDebugBuf, "realloc: %d--------", realloc);
1102 return realloc;
1103 }
1104
canUsePrevFrame()1105 bool ExynosMPP::canUsePrevFrame()
1106 {
1107 if ((mAssignedDisplay && !mAssignedDisplay->mDisplayControl.skipM2mProcessing) ||
1108 !exynosHWCControl.skipM2mProcessing)
1109 return false;
1110
1111 /* virtual display always require composition */
1112 if (mAllocOutBufFlag == false)
1113 return false;
1114
1115 if (mPrevFrameInfo.srcNum != mAssignedSources.size())
1116 return false;
1117
1118 for (uint32_t i = 0; i < mPrevFrameInfo.srcNum; i++) {
1119 if ((mPrevFrameInfo.srcInfo[i].bufferHandle != mAssignedSources[i]->mSrcImg.bufferHandle) ||
1120 (mPrevFrameInfo.srcInfo[i].x != mAssignedSources[i]->mSrcImg.x) ||
1121 (mPrevFrameInfo.srcInfo[i].y != mAssignedSources[i]->mSrcImg.y) ||
1122 (mPrevFrameInfo.srcInfo[i].w != mAssignedSources[i]->mSrcImg.w) ||
1123 (mPrevFrameInfo.srcInfo[i].h != mAssignedSources[i]->mSrcImg.h) ||
1124 (mPrevFrameInfo.srcInfo[i].format != mAssignedSources[i]->mSrcImg.format) ||
1125 (mPrevFrameInfo.srcInfo[i].usageFlags != mAssignedSources[i]->mSrcImg.usageFlags) ||
1126 (mPrevFrameInfo.srcInfo[i].dataSpace != mAssignedSources[i]->mSrcImg.dataSpace) ||
1127 (mPrevFrameInfo.srcInfo[i].blending != mAssignedSources[i]->mSrcImg.blending) ||
1128 (mPrevFrameInfo.srcInfo[i].transform != mAssignedSources[i]->mSrcImg.transform) ||
1129 (mPrevFrameInfo.srcInfo[i].compressed != mAssignedSources[i]->mSrcImg.compressed) ||
1130 (mPrevFrameInfo.srcInfo[i].planeAlpha != mAssignedSources[i]->mSrcImg.planeAlpha) ||
1131 (mPrevFrameInfo.dstInfo[i].x != mAssignedSources[i]->mMidImg.x) ||
1132 (mPrevFrameInfo.dstInfo[i].y != mAssignedSources[i]->mMidImg.y) ||
1133 (mPrevFrameInfo.dstInfo[i].w != mAssignedSources[i]->mMidImg.w) ||
1134 (mPrevFrameInfo.dstInfo[i].h != mAssignedSources[i]->mMidImg.h) ||
1135 (mPrevFrameInfo.dstInfo[i].format != mAssignedSources[i]->mMidImg.format))
1136 return false;
1137 }
1138
1139 int32_t prevDstIndex = (mCurrentDstBuf + NUM_MPP_DST_BUFS(mLogicalType) - 1)% NUM_MPP_DST_BUFS(mLogicalType);
1140 if (mDstImgs[prevDstIndex].bufferHandle == NULL)
1141 return false;
1142
1143 return true;
1144 }
1145
setupLayer(exynos_mpp_img_info * srcImgInfo,struct exynos_image & src,struct exynos_image & dst)1146 int32_t ExynosMPP::setupLayer(exynos_mpp_img_info *srcImgInfo, struct exynos_image &src, struct exynos_image &dst)
1147 {
1148 int ret = NO_ERROR;
1149
1150 if (srcImgInfo->mppLayer == NULL) {
1151 if ((srcImgInfo->mppLayer = mAcrylicHandle->createLayer()) == NULL)
1152 {
1153 MPP_LOGE("%s:: Fail to create layer", __func__);
1154 return -EINVAL;
1155 }
1156 }
1157
1158 if (src.bufferHandle == NULL) {
1159 MPP_LOGE("%s:: Invalid source handle", __func__);
1160 return -EINVAL;
1161 }
1162
1163 buffer_handle_t srcHandle = NULL;
1164 if (src.bufferHandle != NULL)
1165 srcHandle = src.bufferHandle;
1166
1167 VendorGraphicBufferMeta gmeta(srcHandle);
1168 int bufFds[MAX_HW2D_PLANES];
1169 size_t bufLength[MAX_HW2D_PLANES];
1170 uint32_t attribute = 0;
1171 uint32_t bufferNum = getBufferNumOfFormat(gmeta.format, getCompressionType(srcHandle));
1172 android_dataspace_t dataspace = src.dataSpace;
1173 if (dataspace == HAL_DATASPACE_UNKNOWN)
1174 {
1175 if (isFormatRgb(gmeta.format))
1176 dataspace = HAL_DATASPACE_V0_SRGB;
1177 else
1178 dataspace = HAL_DATASPACE_V0_BT601_625;
1179 }
1180
1181 if (bufferNum == 0)
1182 {
1183 MPP_LOGE("%s:: Fail to get bufferNum(%d), format(0x%8x, afbc %d)", __func__, bufferNum,
1184 gmeta.format, isAFBCCompressed(srcHandle));
1185 return -EINVAL;
1186 }
1187 bufFds[0] = gmeta.fd;
1188 bufFds[1] = gmeta.fd1;
1189 bufFds[2] = gmeta.fd2;
1190 if (getBufLength(srcHandle, MAX_HW2D_PLANES, bufLength, gmeta.format, src.fullWidth, src.fullHeight) != NO_ERROR) {
1191 MPP_LOGE("%s:: invalid bufferLength(%zu, %zu, %zu), format(0x%8x)", __func__,
1192 bufLength[0], bufLength[1], bufLength[2], gmeta.format);
1193 return -EINVAL;
1194 }
1195
1196 /* HDR process */
1197 if (hasHdrInfo(src)) {
1198 unsigned int max = (src.metaParcel.sHdrStaticInfo.sType1.mMaxDisplayLuminance/10000);
1199 unsigned int min = src.metaParcel.sHdrStaticInfo.sType1.mMinDisplayLuminance;
1200
1201 srcImgInfo->mppLayer->setMasterDisplayLuminance(min,max);
1202 MPP_LOGD(eDebugMPP, "HWC2: G2D luminance min %d, max %d", min, max);
1203 MPP_LOGD(eDebugMPP|eDebugFence, "G2D getting HDR source!");
1204 }
1205
1206 /* Transfer MetaData */
1207 if (src.hasMetaParcel) {
1208 srcImgInfo->mppLayer->setLayerData(&src.metaParcel, sizeof(src.metaParcel));
1209 }
1210
1211 srcImgInfo->bufferType = getBufferType(srcHandle);
1212 if (srcImgInfo->bufferType == MPP_BUFFER_SECURE_DRM)
1213 attribute |= AcrylicCanvas::ATTR_PROTECTED;
1214 if (src.compressed)
1215 attribute |= AcrylicCanvas::ATTR_COMPRESSED;
1216
1217 srcImgInfo->bufferHandle = srcHandle;
1218 srcImgInfo->acrylicAcquireFenceFd =
1219 hwcCheckFenceDebug(mAssignedDisplay, FENCE_TYPE_SRC_ACQUIRE, FENCE_IP_G2D, src.acquireFenceFd);
1220
1221 MPP_LOGD(eDebugMPP|eDebugFence, "source configuration:");
1222 MPP_LOGD(eDebugMPP, "\tImageDimension[%d, %d], ImageType[0x%8x, 0x%8x]",
1223 src.fullWidth, src.fullHeight,
1224 gmeta.format, dataspace);
1225 MPP_LOGD(eDebugMPP|eDebugFence, "\tImageBuffer handle: %p, fds[%d, %d, %d], bufLength[%zu, %zu, %zu], bufferNum: %d, acquireFence: %d, attribute: %d",
1226 srcHandle, bufFds[0], bufFds[1], bufFds[2], bufLength[0], bufLength[1], bufLength[2],
1227 bufferNum, srcImgInfo->acrylicAcquireFenceFd, attribute);
1228 MPP_LOGD(eDebugMPP, "\tsrc_rect[%d, %d, %d, %d], dst_rect[%d, %d, %d, %d], transform(0x%4x)",
1229 (int)src.x, (int)src.y, (int)(src.x + src.w), (int)(src.y + src.h),
1230 (int)dst.x, (int)dst.y, (int)(dst.x + dst.w), (int)(dst.y + dst.h), src.transform);
1231
1232 srcImgInfo->mppLayer->setImageDimension(src.fullWidth, src.fullHeight);
1233
1234 if (gmeta.format == HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SP_M_PRIV) {
1235 srcImgInfo->mppLayer->setImageType(HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SP_M, dataspace);
1236 } else {
1237 srcImgInfo->mppLayer->setImageType(gmeta.format, dataspace);
1238 }
1239
1240 if (mPhysicalType == MPP_G2D) {
1241 setFenceName(srcImgInfo->acrylicAcquireFenceFd, FENCE_G2D_SRC_LAYER);
1242 setFenceInfo(srcImgInfo->acrylicAcquireFenceFd, mAssignedDisplay,
1243 FENCE_TYPE_SRC_ACQUIRE, FENCE_IP_G2D, FENCE_TO);
1244 } else if (mPhysicalType == MPP_MSC) {
1245 setFenceName(srcImgInfo->acrylicAcquireFenceFd, FENCE_MSC_SRC_LAYER);
1246 setFenceInfo(srcImgInfo->acrylicAcquireFenceFd, mAssignedDisplay,
1247 FENCE_TYPE_SRC_ACQUIRE, FENCE_IP_MSC, FENCE_TO);
1248 } else {
1249 MPP_LOGE("%s:: invalid mPhysicalType(%d)", __func__, mPhysicalType);
1250 }
1251
1252 srcImgInfo->mppLayer->setImageBuffer(bufFds, bufLength, bufferNum,
1253 srcImgInfo->acrylicAcquireFenceFd, attribute);
1254
1255 if (mMaxSrcLayerNum > 1) {
1256 srcImgInfo->mppLayer->setCompositMode(src.blending, (uint8_t)(255 * src.planeAlpha), src.zOrder);
1257 } else {
1258 srcImgInfo->mppLayer->setCompositMode(src.blending, 255, src.zOrder);
1259 }
1260
1261 hwc_rect_t src_rect = {(int)src.x, (int)src.y, (int)(src.x + src.w), (int)(src.y + src.h)};
1262 hwc_rect_t dst_rect = {(int)dst.x, (int)dst.y, (int)(dst.x + dst.w), (int)(dst.y + dst.h)};
1263
1264 if ((mAssignedDisplay != NULL) &&
1265 ((mAssignedDisplay->mType == HWC_DISPLAY_VIRTUAL) ||
1266 (mAssignedDisplay->mType == HWC_DISPLAY_EXTERNAL)))
1267 srcImgInfo->mppLayer->setCompositArea(src_rect, dst_rect, src.transform, AcrylicLayer::ATTR_NORESAMPLING);
1268 else {
1269 if(isFormatYUV(src.format))
1270 srcImgInfo->mppLayer->setCompositArea(src_rect, dst_rect, src.transform, AcrylicLayer::ATTR_NORESAMPLING);
1271 else
1272 srcImgInfo->mppLayer->setCompositArea(src_rect, dst_rect, src.transform);
1273 }
1274
1275 srcImgInfo->acrylicAcquireFenceFd = -1;
1276 srcImgInfo->format = gmeta.format;
1277
1278 if (gmeta.format == HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SP_M_PRIV) {
1279 srcImgInfo->format = HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SP_M;
1280 }
1281
1282 return ret;
1283 }
1284
getDstMetaInfo(android_dataspace_t dstDataspace)1285 dstMetaInfo_t ExynosMPP::getDstMetaInfo(android_dataspace_t dstDataspace)
1286 {
1287 dstMetaInfo_t metaInfo;
1288
1289 if ((mAssignedSources.size() <= 1) &&
1290 (mAssignedSources[0]->mSrcImg.dataSpace == dstDataspace)) {
1291 metaInfo.minLuminance =
1292 (uint16_t)mAssignedSources[0]->mSrcImg.metaParcel.sHdrStaticInfo.sType1.mMinDisplayLuminance;
1293 metaInfo.maxLuminance =
1294 (uint16_t)(mAssignedSources[0]->mSrcImg.metaParcel.sHdrStaticInfo.sType1.mMaxDisplayLuminance/10000);
1295 } else {
1296 // minLuminance: 0.0001nit unit, maxLuminance: 1nit unit
1297 metaInfo.minLuminance = (uint16_t)(mAssignedDisplay->mMinLuminance * 10000);
1298 metaInfo.maxLuminance = (uint16_t)mAssignedDisplay->mMaxLuminance;
1299 }
1300
1301 return metaInfo;
1302 }
1303
setupDst(exynos_mpp_img_info * dstImgInfo)1304 int32_t ExynosMPP::setupDst(exynos_mpp_img_info *dstImgInfo)
1305 {
1306 int ret = NO_ERROR;
1307 bool isComposition = (mMaxSrcLayerNum > 1);
1308 buffer_handle_t dstHandle = dstImgInfo->bufferHandle;
1309 int bufFds[MAX_HW2D_PLANES];
1310 size_t bufLength[MAX_HW2D_PLANES];
1311 uint32_t attribute = 0;
1312 uint32_t bufferNum = getBufferNumOfFormat(dstImgInfo->format, getCompressionType(dstHandle));
1313 if (bufferNum == 0)
1314 {
1315 MPP_LOGE("%s:: Fail to get bufferNum(%d), format(0x%8x, afbc %d)", __func__, bufferNum,
1316 dstImgInfo->format, isAFBCCompressed(dstHandle));
1317 return -EINVAL;
1318 }
1319
1320 android_dataspace_t dataspace = HAL_DATASPACE_UNKNOWN;
1321 VendorGraphicBufferMeta gmeta(dstHandle);
1322
1323 if (isComposition) {
1324 if (isFormatRgb(dstImgInfo->format)) {
1325 if ((mAssignedDisplay != NULL) &&
1326 (mAssignedDisplay->mColorMode != HAL_COLOR_MODE_NATIVE))
1327 dataspace = colorModeToDataspace(mAssignedDisplay->mColorMode);
1328 } else {
1329 dataspace =
1330 (android_dataspace)(HAL_DATASPACE_STANDARD_BT709 | HAL_DATASPACE_TRANSFER_GAMMA2_2 | HAL_DATASPACE_RANGE_LIMITED);
1331 }
1332 } else {
1333 dataspace = mAssignedSources[0]->mMidImg.dataSpace;
1334 }
1335
1336 if (dataspace == HAL_DATASPACE_UNKNOWN)
1337 {
1338 if (isFormatRgb(dstImgInfo->format))
1339 dataspace = HAL_DATASPACE_V0_SRGB;
1340 else
1341 dataspace = HAL_DATASPACE_V0_BT601_625;
1342 }
1343
1344 bufFds[0] = gmeta.fd;
1345 bufFds[1] = gmeta.fd1;
1346 bufFds[2] = gmeta.fd2;
1347 if (getBufLength(dstHandle, MAX_HW2D_PLANES, bufLength, dstImgInfo->format,
1348 gmeta.stride, gmeta.vstride) != NO_ERROR) {
1349 MPP_LOGE("%s:: invalid bufferLength(%zu, %zu, %zu), format(0x%8x)", __func__,
1350 bufLength[0], bufLength[1], bufLength[2], dstImgInfo->format);
1351 return -EINVAL;
1352 }
1353
1354 dstImgInfo->bufferType = getBufferType(dstHandle);
1355 if (dstImgInfo->bufferType == MPP_BUFFER_SECURE_DRM)
1356 attribute |= AcrylicCanvas::ATTR_PROTECTED;
1357
1358 if (mAssignedDisplay != NULL)
1359 mAcrylicHandle->setCanvasDimension(pixel_align(mAssignedDisplay->mXres, G2D_JUSTIFIED_DST_ALIGN),
1360 pixel_align(mAssignedDisplay->mYres, G2D_JUSTIFIED_DST_ALIGN));
1361
1362 /* setup dst */
1363 if (needCompressDstBuf()) {
1364 attribute |= AcrylicCanvas::ATTR_COMPRESSED;
1365 }
1366
1367 if (mPhysicalType == MPP_G2D) {
1368 setFenceName(dstImgInfo->acrylicAcquireFenceFd, FENCE_G2D_DST_DPP);
1369 /* Might be closed next frame */
1370 setFenceInfo(dstImgInfo->acrylicAcquireFenceFd, mAssignedDisplay,
1371 FENCE_TYPE_DST_ACQUIRE, FENCE_IP_G2D, FENCE_TO);
1372 } else if (mPhysicalType == MPP_MSC) {
1373 setFenceName(dstImgInfo->acrylicAcquireFenceFd, FENCE_MSC_DST_DPP);
1374 /* Might be closed next frame */
1375 setFenceInfo(dstImgInfo->acrylicAcquireFenceFd, mAssignedDisplay,
1376 FENCE_TYPE_DST_ACQUIRE, FENCE_IP_MSC, FENCE_TO);
1377 } else {
1378 MPP_LOGE("%s:: invalid mPhysicalType(%d)", __func__, mPhysicalType);
1379 }
1380
1381 mAcrylicHandle->setCanvasImageType(dstImgInfo->format, dataspace);
1382
1383 if ((mLogicalType == MPP_LOGICAL_G2D_COMBO) &&
1384 (mAssignedDisplay != NULL) &&
1385 (mAssignedDisplay->mType == HWC_DISPLAY_VIRTUAL) &&
1386 (((ExynosVirtualDisplay *)mAssignedDisplay)->mIsWFDState == (int)LLWFD)) {
1387 mAcrylicHandle->setCanvasImageType(HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SPN, dataspace);
1388 dstImgInfo->acrylicAcquireFenceFd = fence_close(dstImgInfo->acrylicAcquireFenceFd,
1389 mAssignedDisplay, FENCE_TYPE_SRC_ACQUIRE, FENCE_IP_G2D);
1390 mAcrylicHandle->setCanvasBuffer(bufFds, bufLength, bufferNum,
1391 dstImgInfo->acrylicAcquireFenceFd, attribute);
1392 mAcrylicHandle->setCanvasOTF(attribute);
1393 }
1394 else {
1395 dstImgInfo->acrylicAcquireFenceFd =
1396 hwcCheckFenceDebug(mAssignedDisplay, FENCE_TYPE_DST_ACQUIRE, FENCE_IP_G2D, dstImgInfo->acrylicAcquireFenceFd);
1397 mAcrylicHandle->setCanvasBuffer(bufFds, bufLength, bufferNum,
1398 dstImgInfo->acrylicAcquireFenceFd, attribute);
1399 }
1400
1401 dstMetaInfo_t metaInfo = getDstMetaInfo(dataspace);
1402 if ((mAssignedDisplay != NULL) &&
1403 (mAssignedDisplay->mType != HWC_DISPLAY_VIRTUAL)) {
1404 mAcrylicHandle->setTargetDisplayLuminance(metaInfo.minLuminance, metaInfo.maxLuminance);
1405 }
1406
1407 MPP_LOGD(eDebugMPP|eDebugFence, "destination configuration:");
1408 MPP_LOGD(eDebugMPP, "\tImageDimension[%d, %d], ImageType[0x%8x, %d], target luminance[%d, %d]",
1409 gmeta.stride, gmeta.vstride,
1410 dstImgInfo->format, dataspace, metaInfo.minLuminance, metaInfo.maxLuminance);
1411 MPP_LOGD(eDebugMPP|eDebugFence, "\tImageBuffer handle: %p, fds[%d, %d, %d], bufLength[%zu, %zu, %zu], bufferNum: %d, acquireFence: %d, attribute: %d",
1412 dstHandle, bufFds[0], bufFds[1], bufFds[2], bufLength[0], bufLength[1], bufLength[2],
1413 bufferNum, dstImgInfo->acrylicAcquireFenceFd, attribute);
1414
1415
1416 dstImgInfo->acrylicAcquireFenceFd = -1;
1417 dstImgInfo->dataspace = dataspace;
1418
1419 return ret;
1420 }
1421
doPostProcessingInternal()1422 int32_t ExynosMPP::doPostProcessingInternal()
1423 {
1424 ATRACE_CALL();
1425 int ret = NO_ERROR;
1426 size_t sourceNum = mAssignedSources.size();
1427
1428 if (mAcrylicHandle == NULL) {
1429 MPP_LOGE("%s:: mAcrylicHandle is NULL", __func__);
1430 return -EINVAL;
1431 }
1432
1433 /* setup source layers */
1434 for(size_t i = 0; i < sourceNum; i++) {
1435 MPP_LOGD(eDebugMPP|eDebugFence, "Setup [%zu] source: %p", i, mAssignedSources[i]);
1436 if ((ret = setupLayer(&mSrcImgs[i], mAssignedSources[i]->mSrcImg, mAssignedSources[i]->mMidImg)) != NO_ERROR) {
1437 MPP_LOGE("%s:: fail to setupLayer[%zu], ret %d",
1438 __func__, i, ret);
1439 return ret;
1440 }
1441 }
1442
1443 if ((ret = setColorConversionInfo()) != NO_ERROR) {
1444 MPP_LOGE("%s:: fail to setColorConversionInfo ret %d",
1445 __func__, ret);
1446 return ret;
1447 }
1448
1449 if (mPrevFrameInfo.srcNum > sourceNum) {
1450 MPP_LOGD(eDebugMPP, "prev sourceNum(%d), current sourceNum(%zu)",
1451 mPrevFrameInfo.srcNum, sourceNum);
1452 for (size_t i = sourceNum; i < mPrevFrameInfo.srcNum; i++)
1453 {
1454 MPP_LOGD(eDebugMPP, "Remove mSrcImgs[%zu], %p", i, mSrcImgs[i].mppLayer);
1455 if (mSrcImgs[i].mppLayer != NULL) {
1456 delete mSrcImgs[i].mppLayer;
1457 mSrcImgs[i].mppLayer = NULL;
1458 }
1459 }
1460 }
1461
1462 if (mAcrylicHandle->layerCount() != mAssignedSources.size()) {
1463 MPP_LOGE("Different layer number, acrylic layers(%d), assigned size(%zu)",
1464 mAcrylicHandle->layerCount(), mAssignedSources.size());
1465 return -EINVAL;
1466 }
1467 MPP_LOGD(eDebugFence, "setupDst ++ mDstImgs[%d] acrylicAcquireFenceFd(%d)",
1468 mCurrentDstBuf, mDstImgs[mCurrentDstBuf].acrylicAcquireFenceFd);
1469
1470 setupDst(&mDstImgs[mCurrentDstBuf]);
1471
1472 MPP_LOGD(eDebugFence, "setupDst -- mDstImgs[%d] acrylicAcquireFenceFd(%d) closed",
1473 mCurrentDstBuf, mDstImgs[mCurrentDstBuf].acrylicAcquireFenceFd);
1474
1475
1476 int usingFenceCnt = 1;
1477 bool acrylicReturn = true;
1478
1479 #ifndef DISABLE_FENCE
1480 if (mUseM2MSrcFence)
1481 usingFenceCnt = sourceNum + 1; // Get and Use src + dst fence
1482 else
1483 usingFenceCnt = 1; // Get and Use only dst fence
1484 int *releaseFences = new int[usingFenceCnt];
1485 int dstBufIdx = usingFenceCnt - 1;
1486 #else
1487 usingFenceCnt = 0; // Get and Use no fences
1488 int dstBufIdx = 0;
1489 int *releaseFences = NULL;
1490 #endif
1491
1492 acrylicReturn = mAcrylicHandle->execute(releaseFences, usingFenceCnt);
1493
1494 if (acrylicReturn == false) {
1495 MPP_LOGE("%s:: fail to excute compositor", __func__);
1496 for(size_t i = 0; i < sourceNum; i++) {
1497 mSrcImgs[i].acrylicReleaseFenceFd = -1;
1498 MPP_LOGE("src[%zu]: ImageDimension[%d, %d], src_rect[%d, %d, %d, %d], dst_rect[%d, %d, %d, %d], transform(0x%4x)",
1499 i,
1500 mAssignedSources[i]->mSrcImg.fullWidth, mAssignedSources[i]->mSrcImg.fullHeight,
1501 mAssignedSources[i]->mSrcImg.x, mAssignedSources[i]->mSrcImg.y,
1502 mAssignedSources[i]->mSrcImg.x + mAssignedSources[i]->mSrcImg.w,
1503 mAssignedSources[i]->mSrcImg.y + mAssignedSources[i]->mSrcImg.h,
1504 mAssignedSources[i]->mMidImg.x, mAssignedSources[i]->mMidImg.y,
1505 mAssignedSources[i]->mMidImg.x + mAssignedSources[i]->mMidImg.w,
1506 mAssignedSources[i]->mMidImg.y + mAssignedSources[i]->mMidImg.h,
1507 mAssignedSources[i]->mSrcImg.transform);
1508 }
1509 mDstImgs[mCurrentDstBuf].acrylicReleaseFenceFd = -1;
1510 ret = -EPERM;
1511 } else {
1512
1513 // set fence informations from acryl
1514 if (mPhysicalType == MPP_G2D) {
1515 setFenceInfo(releaseFences[dstBufIdx], mAssignedDisplay,
1516 FENCE_TYPE_DST_ACQUIRE, FENCE_IP_G2D, FENCE_FROM);
1517 if (usingFenceCnt > 1) {
1518 for(size_t i = 0; i < sourceNum; i++) {
1519 // TODO DPU release fence is tranferred to m2mMPP's source layer fence
1520 setFenceInfo(releaseFences[i], mAssignedDisplay,
1521 FENCE_TYPE_SRC_RELEASE, FENCE_IP_G2D, FENCE_FROM);
1522 }
1523 }
1524 } else if (mPhysicalType == MPP_MSC) {
1525 setFenceInfo(releaseFences[dstBufIdx], mAssignedDisplay,
1526 FENCE_TYPE_DST_ACQUIRE, FENCE_IP_MSC, FENCE_FROM);
1527 if (usingFenceCnt > 1) {
1528 for(size_t i = 0; i < sourceNum; i++) {
1529 // TODO DPU release fence is tranferred to m2mMPP's source layer fence
1530 setFenceInfo(releaseFences[i], mAssignedDisplay,
1531 FENCE_TYPE_SRC_RELEASE, FENCE_IP_MSC, FENCE_FROM);
1532 }
1533 }
1534 } else {
1535 MPP_LOGE("%s:: invalid mPhysicalType(%d)", __func__, mPhysicalType);
1536 }
1537
1538 if ((mLogicalType == MPP_LOGICAL_G2D_COMBO) &&
1539 (mAssignedDisplay != NULL) &&
1540 (mAssignedDisplay->mType == HWC_DISPLAY_VIRTUAL)) {
1541 if (((ExynosVirtualDisplay *)mAssignedDisplay)->mIsWFDState == (int)LLWFD) {
1542 if (usingFenceCnt != 0) // Use no fences
1543 releaseFences[dstBufIdx] = fence_close(releaseFences[dstBufIdx],
1544 mAssignedDisplay, FENCE_TYPE_SRC_RELEASE, FENCE_IP_G2D); // Close dst buf's fence
1545 }
1546 if (mUseM2MSrcFence) {
1547 if (((ExynosVirtualDisplay *)mAssignedDisplay)->mIsWFDState != (int)GOOGLEWFD) {
1548 for (size_t i = 0; i < sourceNum; i++)
1549 releaseFences[i] = fence_close(releaseFences[i],
1550 mAssignedDisplay, FENCE_TYPE_SRC_RELEASE, FENCE_IP_G2D);
1551 }
1552 }
1553 }
1554
1555 if (usingFenceCnt == 0) { // Use no fences
1556 for(size_t i = 0; i < sourceNum; i++) {
1557 mSrcImgs[i].acrylicReleaseFenceFd = -1;
1558 }
1559 mDstImgs[mCurrentDstBuf].acrylicReleaseFenceFd = -1;
1560 } else {
1561 for(size_t i = 0; i < sourceNum; i++) {
1562 if (mUseM2MSrcFence)
1563 mSrcImgs[i].acrylicReleaseFenceFd =
1564 hwcCheckFenceDebug(mAssignedDisplay, FENCE_TYPE_SRC_RELEASE, FENCE_IP_G2D, releaseFences[i]);
1565 else
1566 mSrcImgs[i].acrylicReleaseFenceFd = -1;
1567 MPP_LOGD(eDebugFence, "mSrcImgs[%zu] acrylicReleaseFenceFd: %d",
1568 i, mSrcImgs[i].acrylicReleaseFenceFd);
1569 }
1570
1571 if (mDstImgs[mCurrentDstBuf].acrylicReleaseFenceFd >= 0) {
1572 MPP_LOGE("mDstImgs[%d].acrylicReleaseFenceFd(%d) is not initialized",
1573 mCurrentDstBuf,
1574 mDstImgs[mCurrentDstBuf].acrylicReleaseFenceFd);
1575 }
1576
1577 if (mPhysicalType == MPP_G2D)
1578 mDstImgs[mCurrentDstBuf].acrylicReleaseFenceFd =
1579 hwcCheckFenceDebug(mAssignedDisplay, FENCE_TYPE_DST_RELEASE, FENCE_IP_G2D, releaseFences[dstBufIdx]);
1580 else if (mPhysicalType == MPP_MSC)
1581 mDstImgs[mCurrentDstBuf].acrylicReleaseFenceFd =
1582 hwcCheckFenceDebug(mAssignedDisplay, FENCE_TYPE_DST_RELEASE, FENCE_IP_MSC, releaseFences[dstBufIdx]);
1583
1584 MPP_LOGD(eDebugFence, "mDstImgs[%d] acrylicReleaseFenceFd: %d , releaseFences[%d]",
1585 mCurrentDstBuf, mDstImgs[mCurrentDstBuf].acrylicReleaseFenceFd, dstBufIdx);
1586 }
1587
1588 if (exynosHWCControl.dumpMidBuf) {
1589 ALOGI("dump image");
1590 exynosHWCControl.dumpMidBuf = false;
1591 if ((mDstImgs[mCurrentDstBuf].acrylicReleaseFenceFd > 0) &&
1592 (sync_wait(mDstImgs[mCurrentDstBuf].acrylicReleaseFenceFd, 1000) < 0)) {
1593 ALOGE("%s:: fence sync_wait error to dump image", __func__);
1594 } else {
1595 buffer_handle_t dstHandle = mDstImgs[mCurrentDstBuf].bufferHandle;
1596 VendorGraphicBufferMeta gmeta(dstHandle);
1597
1598 ALOGI("dump image fw: %d, fh:%d, size: %d", gmeta.stride, gmeta.vstride, gmeta.size);
1599 FILE *fp;
1600 fp = fopen(MPP_DUMP_PATH,"ab");
1601
1602 if (fp) {
1603 void *temp = mmap(0, gmeta.size, PROT_READ|PROT_WRITE, MAP_SHARED, gmeta.fd, 0);
1604 if (temp) {
1605 ALOGI("write...%p", temp);
1606 int write_size = fwrite(temp, gmeta.size, 1, fp);
1607 if (write_size < 0) {
1608 ALOGI("write error: %s", strerror(errno));
1609 } else {
1610 ALOGI("write size: %d", write_size);
1611 }
1612 munmap(temp, gmeta.size);
1613 } else {
1614 ALOGE("mmap is NULL %s", strerror(errno));
1615 }
1616 fclose(fp);
1617 } else {
1618 ALOGE("open fail %s", strerror(errno));
1619 }
1620 }
1621 }
1622 }
1623
1624 #ifndef DISABLE_FENCE
1625 delete [] releaseFences;
1626 #endif
1627
1628 return ret;
1629 }
1630
canSkipProcessing()1631 bool ExynosMPP::canSkipProcessing()
1632 {
1633 if ((mAssignedDisplay == NULL) || (mAssignedSources.size() == 0))
1634 return true;
1635 ExynosMPPSource *source = mAssignedSources[0];
1636 exynos_image dst = source->mMidImg;
1637 if ((mLogicalType == MPP_LOGICAL_G2D_RGB) ||
1638 (mLogicalType == MPP_LOGICAL_G2D_COMBO)) {
1639 dst = mAssignedDisplay->mExynosCompositionInfo.mDstImg;
1640 }
1641 return ((needDstBufRealloc(dst, mCurrentDstBuf) == false) & canUsePrevFrame());
1642
1643 }
1644
1645 /**
1646 * @param src
1647 * @param dst
1648 * @return int32_t releaseFenceFd of src buffer
1649 */
doPostProcessing(struct exynos_image & src,struct exynos_image & dst)1650 int32_t ExynosMPP::doPostProcessing(struct exynos_image &src, struct exynos_image &dst)
1651 {
1652 ATRACE_CALL();
1653 MPP_LOGD(eDebugMPP, "total assigned sources (%zu)++++++++", mAssignedSources.size());
1654
1655 int ret = NO_ERROR;
1656 bool realloc = false;
1657 if (mAssignedSources.size() == 0) {
1658 MPP_LOGE("Assigned source size(%zu) is not valid",
1659 mAssignedSources.size());
1660 ret = -EINVAL;
1661 goto save_frame_info;
1662 }
1663
1664 // Check whether destination buffer allocation is required
1665 if (mAllocOutBufFlag) {
1666 if ((realloc = needDstBufRealloc(dst, mCurrentDstBuf)) == true) {
1667 // allocate mDstImgs[mCurrentDstBuf]
1668 uint32_t bufAlign = getOutBufAlign();
1669 bool isComposition = (mMaxSrcLayerNum > 1);
1670 if (isComposition)
1671 dst.format = DEFAULT_MPP_DST_FORMAT;
1672
1673 uint32_t allocFormat = dst.format;
1674 if (mFreeOutBufFlag == false)
1675 allocFormat = DEFAULT_MPP_DST_FORMAT;
1676
1677 if ((allocFormat == HAL_PIXEL_FORMAT_RGBA_1010102) ||
1678 (allocFormat == HAL_PIXEL_FORMAT_GOOGLE_NV12_SP_10B) ||
1679 (allocFormat == HAL_PIXEL_FORMAT_YCBCR_P010))
1680 allocFormat = DEFAULT_MPP_DST_FORMAT;
1681
1682 ret = allocOutBuf(ALIGN_UP(mAssignedDisplay->mXres, bufAlign),
1683 ALIGN_UP(mAssignedDisplay->mYres, bufAlign),
1684 allocFormat, dst.usageFlags, mCurrentDstBuf);
1685 }
1686 if (ret < 0) {
1687 MPP_LOGE("%s:: fail to allocate dst buffer[%d]", __func__, mCurrentDstBuf);
1688 goto save_frame_info;
1689 }
1690 if (mDstImgs[mCurrentDstBuf].format != dst.format) {
1691 MPP_LOGD(eDebugMPP, "dst format is changed (%d -> %d)",
1692 mDstImgs[mCurrentDstBuf].format, dst.format);
1693 mDstImgs[mCurrentDstBuf].format = dst.format;
1694 }
1695 }
1696
1697 if ((realloc == false) && canUsePrevFrame()) {
1698 mCurrentDstBuf = (mCurrentDstBuf + NUM_MPP_DST_BUFS(mLogicalType) - 1)% NUM_MPP_DST_BUFS(mLogicalType);
1699 MPP_LOGD(eDebugMPP|eDebugFence, "Reuse previous frame, dstImg[%d]", mCurrentDstBuf);
1700 for (uint32_t i = 0; i < mAssignedSources.size(); i++) {
1701 mAssignedSources[i]->mSrcImg.acquireFenceFd =
1702 fence_close(mAssignedSources[i]->mSrcImg.acquireFenceFd,
1703 mAssignedDisplay, FENCE_TYPE_SRC_ACQUIRE, FENCE_IP_G2D);
1704 }
1705 goto save_frame_info;
1706 }
1707
1708 /* G2D or sclaer case */
1709 if ((ret = doPostProcessingInternal()) < 0) {
1710 MPP_LOGE("%s:: fail to post processing, ret %d",
1711 __func__, ret);
1712 goto save_frame_info;
1713 }
1714
1715 save_frame_info:
1716 /* Save current frame information for next frame*/
1717 mPrevAssignedDisplayType = mAssignedDisplay->mType;
1718 mPrevFrameInfo.srcNum = (uint32_t)mAssignedSources.size();
1719 for (uint32_t i = 0; i < mPrevFrameInfo.srcNum; i++) {
1720 mPrevFrameInfo.srcInfo[i] = mAssignedSources[i]->mSrcImg;
1721 mPrevFrameInfo.dstInfo[i] = mAssignedSources[i]->mMidImg;
1722 }
1723
1724 MPP_LOGD(eDebugMPP, "mPrevAssignedState: %d, mPrevAssignedDisplayType: %d--------------",
1725 mAssignedState, mAssignedDisplay->mType);
1726
1727 return ret;
1728 }
1729
1730 /*
1731 * This function should be called after doPostProcessing()
1732 * because doPostProcessing() sets
1733 * mSrcImgs[].mppImg.releaseFenceFd
1734 */
getSrcReleaseFence(uint32_t srcIndex)1735 int32_t ExynosMPP::getSrcReleaseFence(uint32_t srcIndex)
1736 {
1737 if (srcIndex >= NUM_MPP_SRC_BUFS)
1738 return -EINVAL;
1739
1740 return mSrcImgs[srcIndex].acrylicReleaseFenceFd;
1741
1742 return -EINVAL;
1743 }
1744
resetSrcReleaseFence()1745 int32_t ExynosMPP::resetSrcReleaseFence()
1746 {
1747 MPP_LOGD(eDebugFence, "");
1748 for (uint32_t i = 0; i < mAssignedSources.size(); i++) {
1749 mSrcImgs[i].acrylicReleaseFenceFd = -1;
1750 }
1751 return NO_ERROR;
1752 }
1753
getDstImageInfo(exynos_image * img)1754 int32_t ExynosMPP::getDstImageInfo(exynos_image *img)
1755 {
1756 if ((mCurrentDstBuf < 0) || (mCurrentDstBuf >= NUM_MPP_DST_BUFS(mLogicalType)) ||
1757 (mAssignedDisplay == NULL)) {
1758 MPP_LOGE("mCurrentDstBuf(%d), mAssignedDisplay(%p)", mCurrentDstBuf, mAssignedDisplay);
1759 return -EINVAL;
1760 }
1761
1762 memset(img, 0, sizeof(exynos_image));
1763 img->acquireFenceFd = -1;
1764 img->releaseFenceFd = -1;
1765
1766 img->compressed = needCompressDstBuf();
1767
1768 if (mDstImgs[mCurrentDstBuf].bufferHandle == NULL) {
1769 img->acquireFenceFd = -1;
1770 img->releaseFenceFd = -1;
1771 return -EFAULT;
1772 } else {
1773 img->bufferHandle = mDstImgs[mCurrentDstBuf].bufferHandle;
1774 VendorGraphicBufferMeta gmeta(img->bufferHandle);
1775 img->fullWidth = gmeta.stride;
1776 img->fullHeight = gmeta.vstride;
1777 if ((mLogicalType == MPP_LOGICAL_G2D_RGB) ||
1778 (mLogicalType == MPP_LOGICAL_G2D_COMBO)) {
1779 if (mAssignedSources.size() == 1) {
1780 img->x = mAssignedSources[0]->mDstImg.x;
1781 img->y = mAssignedSources[0]->mDstImg.y;
1782 img->w = mAssignedSources[0]->mDstImg.w;
1783 img->h = mAssignedSources[0]->mDstImg.h;
1784 } else {
1785 img->x = 0;
1786 img->y = 0;
1787 img->w = mAssignedDisplay->mXres;
1788 img->h = mAssignedDisplay->mXres;
1789 }
1790 } else {
1791 img->x = mAssignedSources[0]->mMidImg.x;
1792 img->y = mAssignedSources[0]->mMidImg.y;
1793 img->w = mAssignedSources[0]->mMidImg.w;
1794 img->h = mAssignedSources[0]->mMidImg.h;
1795 img->needColorTransform =
1796 mAssignedSources[0]->mMidImg.needColorTransform;
1797 }
1798
1799 img->format = mDstImgs[mCurrentDstBuf].format;
1800 MPP_LOGD(eDebugFence, "get dstBuf[%d] accquireFence(%d)", mCurrentDstBuf,
1801 mDstImgs[mCurrentDstBuf].acrylicAcquireFenceFd);
1802 img->acquireFenceFd = mDstImgs[mCurrentDstBuf].acrylicAcquireFenceFd;
1803 img->releaseFenceFd = mDstImgs[mCurrentDstBuf].acrylicReleaseFenceFd;
1804 img->dataSpace = mDstImgs[mCurrentDstBuf].dataspace;
1805 }
1806 return NO_ERROR;
1807 }
1808
1809 /*
1810 * This function should be called after getDstReleaseFence()
1811 * by ExynosDisplay
1812 */
setDstAcquireFence(int acquireFence)1813 int32_t ExynosMPP::setDstAcquireFence(int acquireFence)
1814 {
1815
1816 int dstBufIndex = 0;
1817
1818 dstBufIndex = mPrivDstBuf;
1819
1820 if (mPrivDstBuf == mCurrentDstBuf)
1821 MPP_LOGD(eDebugFence|eDebugMPP,
1822 "M2MMPP : same buffer was reused idx %d, %d",mPrivDstBuf, mCurrentDstBuf);
1823
1824 if (dstBufIndex < 0 || dstBufIndex >= NUM_MPP_DST_BUFS(mLogicalType)) {
1825 // TODO fence_close..
1826 acquireFence = fence_close(acquireFence, mAssignedDisplay, FENCE_TYPE_DST_ACQUIRE, FENCE_IP_ALL);
1827 mPrivDstBuf = mCurrentDstBuf;
1828 return -EINVAL;
1829 }
1830
1831 if (acquireFence < 0) {
1832 mPrivDstBuf = mCurrentDstBuf;
1833 return -EINVAL;
1834 }
1835
1836 if (mDstImgs[dstBufIndex].acrylicAcquireFenceFd >= 0) {
1837 MPP_LOGD(eDebugFence,"mDstImgs[%d].acrylicAcquireFenceFd: %d is closed", dstBufIndex,
1838 mDstImgs[dstBufIndex].acrylicAcquireFenceFd);
1839 fence_close(mDstImgs[dstBufIndex].acrylicAcquireFenceFd, mAssignedDisplay,
1840 FENCE_TYPE_DST_ACQUIRE, FENCE_IP_ALL);
1841 }
1842 if (mPhysicalType == MPP_MSC)
1843 mDstImgs[dstBufIndex].acrylicAcquireFenceFd =
1844 hwcCheckFenceDebug(mAssignedDisplay, FENCE_TYPE_DST_ACQUIRE, FENCE_IP_MSC, acquireFence);
1845 else
1846 mDstImgs[dstBufIndex].acrylicAcquireFenceFd =
1847 hwcCheckFenceDebug(mAssignedDisplay, FENCE_TYPE_DST_ACQUIRE, FENCE_IP_G2D, acquireFence);
1848
1849 MPP_LOGD(eDebugFence,"->mDstImgs[%d].acrylicAcquireFenceFd: %d", dstBufIndex,
1850 mDstImgs[dstBufIndex].acrylicAcquireFenceFd);
1851
1852 mPrivDstBuf = mCurrentDstBuf;
1853
1854 return NO_ERROR;
1855 }
1856
resetDstReleaseFence()1857 int32_t ExynosMPP::resetDstReleaseFence()
1858 {
1859 MPP_LOGD(eDebugFence, "");
1860
1861 if (mCurrentDstBuf < 0 || mCurrentDstBuf >= NUM_MPP_DST_BUFS(mLogicalType))
1862 return -EINVAL;
1863
1864 mDstImgs[mCurrentDstBuf].acrylicReleaseFenceFd = -1;
1865
1866 return NO_ERROR;
1867 }
1868
requestHWStateChange(uint32_t state)1869 int32_t ExynosMPP::requestHWStateChange(uint32_t state)
1870 {
1871 MPP_LOGD(eDebugMPP|eDebugFence|eDebugBuf, "state: %d", state);
1872 /* Set HW state to running */
1873 if (mHWState == state) {
1874 if ((mPhysicalType == MPP_G2D) && (state == MPP_HW_STATE_IDLE) && (mHWBusyFlag == false)) {
1875 int ret = NO_ERROR;
1876 if ((ret = prioritize(-1)) != NO_ERROR)
1877 MPP_LOGI("prioritize (%d) will be applied on next work", ret);
1878 }
1879 return NO_ERROR;
1880 }
1881
1882 if (state == MPP_HW_STATE_RUNNING)
1883 mHWState = MPP_HW_STATE_RUNNING;
1884 else if (state == MPP_HW_STATE_IDLE) {
1885 if (mLastStateFenceFd >= 0)
1886 mResourceManageThread->addStateFence(mLastStateFenceFd);
1887 else
1888 mHWState = MPP_HW_STATE_IDLE;
1889 mLastStateFenceFd = -1;
1890
1891 if ((mPhysicalType == MPP_G2D) && (mHWBusyFlag == false)) {
1892 int ret = NO_ERROR;
1893 if ((ret = prioritize(-1)) != NO_ERROR)
1894 MPP_LOGI("prioritize (%d) is not applied on next work", ret);
1895 }
1896
1897 /* Free all of output buffers */
1898 if (mMPPType == MPP_TYPE_M2M) {
1899 for(uint32_t i = 0; i < NUM_MPP_DST_BUFS(mLogicalType); i++) {
1900 exynos_mpp_img_info freeDstBuf = mDstImgs[i];
1901 memset(&mDstImgs[i], 0, sizeof(mDstImgs[i]));
1902 mDstImgs[i].acrylicAcquireFenceFd = freeDstBuf.acrylicAcquireFenceFd;
1903 mDstImgs[i].acrylicReleaseFenceFd = freeDstBuf.acrylicReleaseFenceFd;
1904 freeDstBuf.acrylicAcquireFenceFd = -1;
1905 freeDstBuf.acrylicReleaseFenceFd = -1;
1906
1907 if (mFreeOutBufFlag == true) {
1908 MPP_LOGD(eDebugMPP|eDebugFence|eDebugBuf, "free outbuf[%d] %p",
1909 i, freeDstBuf.bufferHandle);
1910 if (freeDstBuf.bufferHandle != NULL && mAllocOutBufFlag) {
1911 freeOutBuf(freeDstBuf);
1912 }
1913 } else {
1914 mDstImgs[i].bufferHandle = freeDstBuf.bufferHandle;
1915 mDstImgs[i].bufferType = freeDstBuf.bufferType;
1916 }
1917 }
1918 }
1919
1920 for (uint32_t i = 0; i < NUM_MPP_SRC_BUFS; i++)
1921 {
1922 if (mSrcImgs[i].mppLayer != NULL) {
1923 delete mSrcImgs[i].mppLayer;
1924 mSrcImgs[i].mppLayer = NULL;
1925 }
1926 }
1927 memset(&mPrevFrameInfo, 0, sizeof(mPrevFrameInfo));
1928 for (int i = 0; i < NUM_MPP_SRC_BUFS; i++) {
1929 mPrevFrameInfo.srcInfo[i].acquireFenceFd = -1;
1930 mPrevFrameInfo.srcInfo[i].releaseFenceFd = -1;
1931 mPrevFrameInfo.dstInfo[i].acquireFenceFd = -1;
1932 mPrevFrameInfo.dstInfo[i].releaseFenceFd = -1;
1933 }
1934 }
1935
1936 return NO_ERROR;
1937 }
1938
setHWStateFence(int32_t fence)1939 int32_t ExynosMPP::setHWStateFence(int32_t fence)
1940 {
1941 MPP_LOGD(eDebugFence, "Update HWState fence, Close(%d), set(%d)",
1942 mLastStateFenceFd, fence);
1943 mLastStateFenceFd = fence;
1944
1945 return NO_ERROR;
1946 }
1947
1948 /**
1949 * @param ..
1950 * @return int32_t
1951 */
setupRestriction()1952 int32_t ExynosMPP::setupRestriction() {
1953
1954 MPP_LOGD(eDebugMPP, "mPhysicalType(%d)", mPhysicalType);
1955
1956 for (uint32_t i = 0; i < RESTRICTION_MAX; i++) {
1957 const restriction_size_element *restriction_size_table = mResourceManager->mSizeRestrictions[i];
1958 for (uint32_t j = 0; j < mResourceManager->mSizeRestrictionCnt[i]; j++) {
1959 if (restriction_size_table[j].key.hwType == mPhysicalType) {
1960 if ((restriction_size_table[j].key.nodeType == NODE_SRC) ||
1961 (restriction_size_table[j].key.nodeType == NODE_NONE)) {
1962 memcpy(&mSrcSizeRestrictions[i], &restriction_size_table[j].sizeRestriction,
1963 sizeof(mSrcSizeRestrictions[i]));
1964 MPP_LOGD(eDebugMPP, "\tSet mSrcSizeRestrictions[%d], "
1965 "[%d, %d, %d, %d, %d, %d, %d, %d, %d, %d, %d, %d, %d, %d, %d, %d]",
1966 i, mSrcSizeRestrictions[i].maxDownScale, mSrcSizeRestrictions[i].maxUpScale,
1967 mSrcSizeRestrictions[i].maxFullWidth, mSrcSizeRestrictions[i].maxFullHeight,
1968 mSrcSizeRestrictions[i].minFullWidth, mSrcSizeRestrictions[i].minFullHeight,
1969 mSrcSizeRestrictions[i].fullWidthAlign, mSrcSizeRestrictions[i].fullHeightAlign,
1970 mSrcSizeRestrictions[i].maxCropWidth, mSrcSizeRestrictions[i].maxCropHeight,
1971 mSrcSizeRestrictions[i].minCropWidth, mSrcSizeRestrictions[i].minCropHeight,
1972 mSrcSizeRestrictions[i].cropXAlign, mSrcSizeRestrictions[i].cropYAlign,
1973 mSrcSizeRestrictions[i].cropWidthAlign, mSrcSizeRestrictions[i].cropHeightAlign);
1974
1975 }
1976 if ((restriction_size_table[j].key.nodeType == NODE_DST) ||
1977 (restriction_size_table[j].key.nodeType == NODE_NONE)) {
1978 memcpy(&mDstSizeRestrictions[i], &restriction_size_table[j].sizeRestriction,
1979 sizeof(mDstSizeRestrictions[i]));
1980 MPP_LOGD(eDebugMPP, "\tSet mDstSizeRestrictions[%d], "
1981 "[%d, %d, %d, %d, %d, %d, %d, %d, %d, %d, %d, %d, %d, %d, %d, %d]",
1982 i, mDstSizeRestrictions[i].maxDownScale, mDstSizeRestrictions[i].maxUpScale,
1983 mDstSizeRestrictions[i].maxFullWidth, mDstSizeRestrictions[i].maxFullHeight,
1984 mDstSizeRestrictions[i].minFullWidth, mDstSizeRestrictions[i].minFullHeight,
1985 mDstSizeRestrictions[i].fullWidthAlign, mDstSizeRestrictions[i].fullHeightAlign,
1986 mDstSizeRestrictions[i].maxCropWidth, mDstSizeRestrictions[i].maxCropHeight,
1987 mDstSizeRestrictions[i].minCropWidth, mDstSizeRestrictions[i].minCropHeight,
1988 mDstSizeRestrictions[i].cropXAlign, mDstSizeRestrictions[i].cropYAlign,
1989 mDstSizeRestrictions[i].cropWidthAlign, mDstSizeRestrictions[i].cropHeightAlign);
1990 }
1991 }
1992 }
1993 }
1994
1995 return NO_ERROR;
1996 }
1997
isSupported(ExynosDisplay & display,struct exynos_image & src,struct exynos_image & dst)1998 int64_t ExynosMPP::isSupported(ExynosDisplay &display, struct exynos_image &src, struct exynos_image &dst)
1999 {
2000 uint32_t maxSrcWidth = getSrcMaxWidth(src);
2001 uint32_t maxSrcHeight = getSrcMaxHeight(src);
2002 uint32_t minSrcWidth = getSrcMinWidth(src);
2003 uint32_t minSrcHeight = getSrcMinHeight(src);
2004 uint32_t srcWidthAlign = getSrcWidthAlign(src);
2005 uint32_t srcHeightAlign = getSrcHeightAlign(src);
2006
2007 uint32_t maxSrcCropWidth = getSrcMaxCropWidth(src);
2008 uint32_t maxSrcCropHeight = getSrcMaxCropHeight(src);
2009 uint32_t maxSrcCropSize = getSrcMaxCropSize(src);
2010 uint32_t minSrcCropWidth = getSrcMinCropWidth(src);
2011 uint32_t minSrcCropHeight = getSrcMinCropHeight(src);
2012 uint32_t srcCropWidthAlign = getSrcCropWidthAlign(src);
2013 uint32_t srcCropHeightAlign = getSrcCropHeightAlign(src);
2014 uint32_t srcXOffsetAlign = getSrcXOffsetAlign(src);
2015 uint32_t srcYOffsetAlign = getSrcYOffsetAlign(src);
2016
2017 uint32_t maxDstWidth = getDstMaxWidth(dst);
2018 uint32_t maxDstHeight = getDstMaxHeight(dst);
2019 uint32_t minDstWidth = getDstMinWidth(dst);
2020 uint32_t minDstHeight = getDstMinHeight(dst);
2021 uint32_t dstWidthAlign = getDstWidthAlign(dst);
2022 uint32_t dstHeightAlign = getDstHeightAlign(dst);
2023 uint32_t dstXOffsetAlign = getDstXOffsetAlign(dst);
2024 uint32_t dstYOffsetAlign = getDstYOffsetAlign(dst);
2025
2026 uint32_t maxDownscale = getMaxDownscale(display, src, dst);
2027 uint32_t maxUpscale = getMaxUpscale(src, dst);
2028
2029 exynos_image rot_dst = dst;
2030 bool isPerpendicular = !!(src.transform & HAL_TRANSFORM_ROT_90);
2031 if (isPerpendicular) {
2032 rot_dst.w = dst.h;
2033 rot_dst.h = dst.w;
2034 }
2035
2036 if (dst.w > maxDstWidth)
2037 return -eMPPExeedMaxDstWidth;
2038 else if (dst.h > maxDstHeight)
2039 return -eMPPExeedMaxDstHeight;
2040 else if (dst.w < minDstWidth)
2041 return -eMPPExeedMinDstWidth;
2042 else if (dst.h < minDstHeight)
2043 return -eMPPExeedMinDstHeight;
2044 else if (src.isDimLayer()) { // Dim layer
2045 if (isDimLayerSupported()) {
2046 return NO_ERROR;
2047 } else {
2048 return -eMPPUnsupportedDIMLayer;
2049 }
2050 }
2051 if (!isSupportedCapability(display, src))
2052 return -eMPPSaveCapability;
2053 else if (!isSrcFormatSupported(src))
2054 return -eMPPUnsupportedFormat;
2055 else if (!isDstFormatSupported(dst))
2056 return -eMPPUnsupportedFormat;
2057 else if (!isDataspaceSupportedByMPP(src, dst))
2058 return -eMPPUnsupportedCSC;
2059 else if (!isSupportedHDR10Plus(src, dst))
2060 return -eMPPUnsupportedDynamicMeta;
2061 else if (!isSupportedBlend(src))
2062 return -eMPPUnsupportedBlending;
2063 else if (!isSupportedTransform(src))
2064 return -eMPPUnsupportedRotation;
2065 else if (src.fullWidth < minSrcWidth)
2066 return -eMPPExeedMinSrcWidth;
2067 else if (src.fullHeight < minSrcHeight)
2068 return -eMPPExeedMinSrcHeight;
2069 else if (src.w < minSrcCropWidth)
2070 return -eMPPExeedSrcWCropMin;
2071 else if (src.h < minSrcCropHeight)
2072 return -eMPPExeedSrcHCropMin;
2073 else if ((dst.w % dstWidthAlign != 0) || (dst.h % dstHeightAlign != 0))
2074 return -eMPPNotAlignedDstSize;
2075 else if (src.w > rot_dst.w * maxDownscale)
2076 return -eMPPExeedMaxDownScale;
2077 else if (rot_dst.w > src.w * maxUpscale)
2078 return -eMPPExeedMaxUpScale;
2079 else if (src.h > rot_dst.h * maxDownscale)
2080 return -eMPPExeedMaxDownScale;
2081 else if (rot_dst.h > src.h * maxUpscale)
2082 return -eMPPExeedMaxUpScale;
2083 else if (!isSupportedDRM(src))
2084 return -eMPPUnsupportedDRM;
2085 else if (!isSupportedHStrideCrop(src))
2086 return -eMPPStrideCrop;
2087 else if (src.fullWidth > maxSrcWidth)
2088 return -eMPPExceedHStrideMaximum;
2089 else if (src.fullWidth % srcWidthAlign != 0)
2090 return -eMPPNotAlignedHStride;
2091
2092 if ((src.w * src.h) > maxSrcCropSize)
2093 return -eMPPExeedSrcCropMax;
2094
2095 if (getDrmMode(src.usageFlags) == NO_DRM) {
2096 if (src.fullHeight > maxSrcHeight)
2097 return -eMPPExceedVStrideMaximum;
2098 else if (src.fullHeight % srcHeightAlign != 0)
2099 return -eMPPNotAlignedVStride;
2100 else if (src.w > maxSrcCropWidth)
2101 return -eMPPExeedSrcWCropMax;
2102 else if (src.h > maxSrcCropHeight)
2103 return -eMPPExeedSrcHCropMax;
2104 else if ((src.w % srcCropWidthAlign != 0) || (src.h % srcCropHeightAlign != 0))
2105 return -eMPPNotAlignedCrop;
2106 else if ((src.x % srcXOffsetAlign != 0) || (src.y % srcYOffsetAlign != 0))
2107 return -eMPPNotAlignedOffset;
2108 }
2109
2110 if ((dst.x % dstXOffsetAlign != 0) || (dst.y % dstYOffsetAlign != 0))
2111 return -eMPPNotAlignedOffset;
2112
2113 if (!isSupportedCompression(src))
2114 return -eMPPUnsupportedCompression;
2115
2116 if (!isSupportLayerColorTransform(src,dst))
2117 return -eMPPUnsupportedColorTransform;
2118
2119 return NO_ERROR;
2120 }
2121
resetMPP()2122 int32_t ExynosMPP::resetMPP()
2123 {
2124 mAssignedState = MPP_ASSIGN_STATE_FREE;
2125 mAssignedDisplay = NULL;
2126 mAssignedSources.clear();
2127 resetUsedCapacity();
2128 mReservedDisplay = -1;
2129 mHWBusyFlag = false;
2130
2131 return NO_ERROR;
2132 }
2133
resetAssignedState()2134 int32_t ExynosMPP::resetAssignedState()
2135 {
2136 for (int i = (int)mAssignedSources.size(); i-- > 0;) {
2137 ExynosMPPSource *mppSource = mAssignedSources[i];
2138 if (mppSource->mOtfMPP == this) {
2139 mppSource->mOtfMPP = NULL;
2140 }
2141 if (mppSource->mM2mMPP == this) {
2142 mppSource->mM2mMPP = NULL;
2143 }
2144 mAssignedSources.removeItemsAt(i);
2145 }
2146
2147 /* Keep status if mAssignedState is MPP_ASSIGN_STATE_RESERVED */
2148 if ((mAssignedState & MPP_ASSIGN_STATE_ASSIGNED) &&
2149 (mAssignedSources.size() == 0)) {
2150 mAssignedState &= ~MPP_ASSIGN_STATE_ASSIGNED;
2151 mAssignedDisplay = NULL;
2152 }
2153
2154 /* All mpp source are removed, reset capacity information */
2155 resetUsedCapacity();
2156
2157 return NO_ERROR;
2158 }
2159
resetAssignedState(ExynosMPPSource * mppSource)2160 int32_t ExynosMPP::resetAssignedState(ExynosMPPSource *mppSource)
2161 {
2162 bool needUpdateCapacity = false;
2163 for (int i = (int)mAssignedSources.size(); i-- > 0;) {
2164 ExynosMPPSource *source = mAssignedSources[i];
2165 if (source == mppSource) {
2166 if (mppSource->mM2mMPP == this) {
2167 mppSource->mM2mMPP = NULL;
2168 }
2169 /* Update information for used capacity */
2170 /* This should be called before mAssignedSources.removeItemsAt(mppSource) */
2171 needUpdateCapacity = removeCapacity(mppSource);
2172
2173 mAssignedSources.removeItemsAt(i);
2174
2175 if (needUpdateCapacity)
2176 updateUsedCapacity();
2177
2178 break;
2179 }
2180 }
2181
2182 /* Keep status if mAssignedState is MPP_ASSIGN_STATE_RESERVED */
2183 if ((mAssignedState & MPP_ASSIGN_STATE_ASSIGNED) &&
2184 (mAssignedSources.size() == 0)) {
2185 mAssignedState &= ~MPP_ASSIGN_STATE_ASSIGNED;
2186 mAssignedDisplay = NULL;
2187 }
2188
2189 return NO_ERROR;
2190 }
2191
reserveMPP(int32_t displayId)2192 int32_t ExynosMPP::reserveMPP(int32_t displayId)
2193 {
2194 mAssignedState |= MPP_ASSIGN_STATE_RESERVED;
2195 mReservedDisplay = displayId;
2196
2197 return NO_ERROR;
2198 }
2199
assignMPP(ExynosDisplay * display,ExynosMPPSource * mppSource)2200 int32_t ExynosMPP::assignMPP(ExynosDisplay *display, ExynosMPPSource* mppSource)
2201 {
2202 mAssignedState |= MPP_ASSIGN_STATE_ASSIGNED;
2203
2204 if (mMPPType == MPP_TYPE_OTF)
2205 mppSource->mOtfMPP = this;
2206 else if (mMPPType == MPP_TYPE_M2M)
2207 mppSource->mM2mMPP = this;
2208 else {
2209 MPP_LOGE("%s:: Invalid mppType(%d)", __func__, mMPPType);
2210 return -EINVAL;
2211 }
2212
2213 mAssignedDisplay = display;
2214
2215 /* Update information for used capacity */
2216 /* This should be called before mAssignedSources.add(mppSource) */
2217 bool needUpdateCapacity = addCapacity(mppSource);
2218
2219 mAssignedSources.add(mppSource);
2220
2221 MPP_LOGD(eDebugCapacity|eDebugMPP, "\tassigned to source(%p) type(%d), mAssignedSources(%zu)",
2222 mppSource, mppSource->mSourceType,
2223 mAssignedSources.size());
2224
2225 if (needUpdateCapacity)
2226 updateUsedCapacity();
2227
2228 if (mMaxSrcLayerNum > 1) {
2229 std::sort(mAssignedSources.begin(), mAssignedSources.end(), exynosMPPSourceComp);
2230 }
2231
2232 return NO_ERROR;
2233 }
2234
getSrcMaxBlendingNum(struct exynos_image __unused & src,struct exynos_image __unused & dst)2235 uint32_t ExynosMPP::getSrcMaxBlendingNum(struct exynos_image __unused &src, struct exynos_image __unused &dst)
2236 {
2237 uint32_t maxSrcLayerNum = mMaxSrcLayerNum;
2238 return maxSrcLayerNum;
2239 }
2240
getAssignedSourceNum()2241 uint32_t ExynosMPP::getAssignedSourceNum()
2242 {
2243 return mAssignedSources.size();
2244 }
2245
2246 /* Based on multi-resolution support */
setDstAllocSize(uint32_t width,uint32_t height)2247 void ExynosMPP::setDstAllocSize(uint32_t width, uint32_t height)
2248 {
2249 switch(width) {
2250 case 720:
2251 mDstAllocatedSize = ((height >= 1480) ? DST_SIZE_HD_PLUS : DST_SIZE_HD);
2252 break;
2253 case 1080:
2254 mDstAllocatedSize = ((height >= 2220) ? DST_SIZE_FHD_PLUS : DST_SIZE_FHD);
2255 break;
2256 case 1440:
2257 mDstAllocatedSize = ((height >= 2960) ? DST_SIZE_WQHD_PLUS : DST_SIZE_WQHD);
2258 break;
2259 default:
2260 mDstAllocatedSize = DST_SIZE_UNKNOWN;
2261 break;
2262 }
2263 }
2264
getDstAllocSize()2265 dst_alloc_buf_size_t ExynosMPP::getDstAllocSize()
2266 {
2267 return mDstAllocatedSize;
2268 }
2269
needPreAllocation()2270 bool ExynosMPP::needPreAllocation()
2271 {
2272 bool ret = false;
2273
2274 if ((mLogicalType == MPP_LOGICAL_G2D_RGB) &&
2275 (mPreAssignDisplayList[mResourceManager->mDevice->mDisplayMode] == HWC_DISPLAY_PRIMARY_BIT))
2276 ret = true;
2277
2278 return ret;
2279 }
2280
isAssignableState(ExynosDisplay * display,struct exynos_image & src,struct exynos_image & dst)2281 bool ExynosMPP::isAssignableState(ExynosDisplay *display, struct exynos_image &src, struct exynos_image &dst)
2282 {
2283 bool isAssignable = false;
2284
2285 if (mAssignedState == MPP_ASSIGN_STATE_FREE) {
2286 if (mHWState == MPP_HW_STATE_IDLE)
2287 isAssignable = true;
2288 else {
2289 if ((mPrevAssignedDisplayType < 0) ||
2290 ((uint32_t)mPrevAssignedDisplayType == display->mType))
2291 isAssignable = true;
2292 else
2293 isAssignable = false;
2294 }
2295 }
2296
2297 if ((mAssignedState & MPP_ASSIGN_STATE_ASSIGNED) && (mAssignedState & MPP_ASSIGN_STATE_RESERVED))
2298 {
2299 if (mReservedDisplay == (int32_t)display->getId()) {
2300 if (mAssignedSources.size() < getSrcMaxBlendingNum(src, dst))
2301 isAssignable = true;
2302 else
2303 isAssignable = false;
2304 } else {
2305 isAssignable = false;
2306 }
2307 } else if ((mAssignedState & MPP_ASSIGN_STATE_ASSIGNED) && !(mAssignedState & MPP_ASSIGN_STATE_RESERVED)) {
2308 if (mAssignedSources.size() < getSrcMaxBlendingNum(src, dst))
2309 isAssignable = true;
2310 else
2311 isAssignable = false;
2312 } else if (mAssignedState & MPP_ASSIGN_STATE_RESERVED) {
2313 if (mReservedDisplay == (int32_t)display->getId())
2314 isAssignable = true;
2315 else
2316 isAssignable = false;
2317 }
2318
2319 MPP_LOGD(eDebugMPP, "\tisAssignableState(%d), assigned size(%zu), getSrcMaxBlendingNum(%d)",
2320 isAssignable, mAssignedSources.size(), getSrcMaxBlendingNum(src, dst));
2321 return isAssignable;
2322 }
isAssignable(ExynosDisplay * display,struct exynos_image & src,struct exynos_image & dst)2323 bool ExynosMPP::isAssignable(ExynosDisplay *display,
2324 struct exynos_image &src, struct exynos_image &dst)
2325 {
2326 bool isAssignable = isAssignableState(display, src, dst);
2327 return (isAssignable && hasEnoughCapa(display, src, dst));
2328 }
2329
hasEnoughCapa(ExynosDisplay * display,struct exynos_image & src,struct exynos_image & dst)2330 bool ExynosMPP::hasEnoughCapa(ExynosDisplay *display, struct exynos_image &src, struct exynos_image &dst)
2331 {
2332 if (mCapacity == -1)
2333 return true;
2334
2335 float totalUsedCapacity = ExynosResourceManager::getResourceUsedCapa(*this);
2336 MPP_LOGD(eDebugCapacity|eDebugMPP, "totalUsedCapacity(%f), mUsedCapacity(%f)",
2337 totalUsedCapacity, mUsedCapacity);
2338
2339 /* mUsedCapacity should be re-calculated including src, dst passed as parameters*/
2340 totalUsedCapacity -= mUsedCapacity;
2341
2342 float requiredCapacity = getRequiredCapacity(display, src, dst);
2343
2344 MPP_LOGD(eDebugCapacity|eDebugMPP, "mCapacity(%f), usedCapacity(%f), RequiredCapacity(%f)",
2345 mCapacity, totalUsedCapacity, requiredCapacity);
2346
2347 if (mCapacity >= (totalUsedCapacity + requiredCapacity))
2348 return true;
2349 else if ((hasHdrInfo(src)) &&
2350 (totalUsedCapacity == 0) && (requiredCapacity < (mCapacity * 1.2))) {
2351 /* HDR video will be excepted from G2D capa calculation */
2352 /* if DRM has assigned before, totalUsedCapacity will be non-zero */
2353 return true;
2354 } else
2355 return false;
2356 }
2357
getPPCIndex(const struct exynos_image & src,const struct exynos_image & dst,uint32_t & formatIndex,uint32_t & rotIndex,uint32_t & scaleIndex,const struct exynos_image & criteria)2358 void ExynosMPP::getPPCIndex(const struct exynos_image &src,
2359 const struct exynos_image &dst,
2360 uint32_t &formatIndex, uint32_t &rotIndex, uint32_t &scaleIndex,
2361 const struct exynos_image &criteria)
2362 {
2363 formatIndex = 0;
2364 rotIndex = 0;
2365 scaleIndex = 0;
2366
2367 /* Compare SBWC, AFBC and 10bitYUV420 first! because can be overlapped with other format */
2368 if (isFormatSBWC(criteria.format) && hasPPC(mPhysicalType, PPC_FORMAT_SBWC, PPC_ROT_NO))
2369 formatIndex = PPC_FORMAT_SBWC;
2370 else if (src.compressed == 1) {
2371 if ((isFormatRgb(criteria.format)) && hasPPC(mPhysicalType, PPC_FORMAT_AFBC_RGB, PPC_ROT_NO))
2372 formatIndex = PPC_FORMAT_AFBC_RGB;
2373 else if ((isFormatYUV(criteria.format)) && hasPPC(mPhysicalType, PPC_FORMAT_AFBC_YUV, PPC_ROT_NO))
2374 formatIndex = PPC_FORMAT_AFBC_YUV;
2375 else {
2376 formatIndex = PPC_FORMAT_RGB32;
2377 MPP_LOGW("%s:: AFBC PPC is not existed. Use default PPC", __func__);
2378 }
2379 } else if (isFormatP010(criteria.format) && hasPPC(mPhysicalType, PPC_FORMAT_P010, PPC_ROT_NO))
2380 formatIndex = PPC_FORMAT_P010;
2381 else if (isFormatYUV420(criteria.format) && hasPPC(mPhysicalType, PPC_FORMAT_YUV420, PPC_ROT_NO))
2382 formatIndex = PPC_FORMAT_YUV420;
2383 else if (isFormatYUV422(criteria.format) && hasPPC(mPhysicalType, PPC_FORMAT_YUV422, PPC_ROT_NO))
2384 formatIndex = PPC_FORMAT_YUV422;
2385 else
2386 formatIndex = PPC_FORMAT_RGB32;
2387
2388 if (((criteria.transform & HAL_TRANSFORM_ROT_90) != 0) ||
2389 (mRotatedSrcCropBW > 0))
2390 rotIndex = PPC_ROT;
2391 else
2392 rotIndex = PPC_ROT_NO;
2393
2394 uint32_t srcResolution = src.w * src.h;
2395 uint32_t dstResolution = dst.w * dst.h;
2396
2397 if (mPhysicalType == MPP_G2D) {
2398 if (srcResolution == dstResolution) {
2399 scaleIndex = PPC_SCALE_NO;
2400 } else if (dstResolution > srcResolution) {
2401 /* scale up case */
2402 if (dstResolution >= (srcResolution * 4))
2403 scaleIndex = PPC_SCALE_UP_4_;
2404 else
2405 scaleIndex = PPC_SCALE_UP_1_4;
2406 } else {
2407 /* scale down case */
2408 if ((dstResolution * 16) <= srcResolution)
2409 scaleIndex = PPC_SCALE_DOWN_16_;
2410 else if (((dstResolution * 9) <= srcResolution) &&
2411 (srcResolution < (dstResolution * 16)))
2412 scaleIndex = PPC_SCALE_DOWN_9_16;
2413 else if (((dstResolution * 4) <= srcResolution) &&
2414 (srcResolution < (dstResolution * 9)))
2415 scaleIndex = PPC_SCALE_DOWN_4_9;
2416 else
2417 scaleIndex = PPC_SCALE_DOWN_1_4;
2418 }
2419 } else scaleIndex = 0; /* MSC doesn't refer scale Index */
2420 }
2421
getPPC(const struct exynos_image & src,const struct exynos_image & dst,const struct exynos_image & criteria,const struct exynos_image * assignCheckSrc,const struct exynos_image * assignCheckDst)2422 float ExynosMPP::getPPC(const struct exynos_image &src,
2423 const struct exynos_image &dst, const struct exynos_image &criteria,
2424 const struct exynos_image *assignCheckSrc,
2425 const struct exynos_image *assignCheckDst)
2426 {
2427 float PPC = 0;
2428 uint32_t formatIndex = 0;
2429 uint32_t rotIndex = 0;
2430 uint32_t scaleIndex = 0;
2431
2432 getPPCIndex(src, dst, formatIndex, rotIndex, scaleIndex, criteria);
2433
2434 if ((rotIndex == PPC_ROT_NO) && (assignCheckSrc != NULL) &&
2435 ((assignCheckSrc->transform & HAL_TRANSFORM_ROT_90) != 0)) {
2436 rotIndex = PPC_ROT;
2437 }
2438
2439 if (mPhysicalType == MPP_G2D || mPhysicalType == MPP_MSC) {
2440 if (hasPPC(mPhysicalType, formatIndex, rotIndex)) {
2441 PPC = ppc_table_map.at(PPC_IDX(mPhysicalType, formatIndex, rotIndex)).ppcList[scaleIndex];
2442 }
2443 }
2444
2445 if (PPC == 0) {
2446 MPP_LOGE("%s:: mPhysicalType(%d), formatIndex(%d), rotIndex(%d), scaleIndex(%d), PPC(%f) is not valid",
2447 __func__, mPhysicalType, formatIndex, rotIndex, scaleIndex, PPC);
2448 PPC = 0.000001; /* It means can't use mPhysicalType H/W */
2449 }
2450
2451 MPP_LOGD(eDebugCapacity, "srcW(%d), srcH(%d), dstW(%d), dstH(%d), rot(%d)"
2452 "formatIndex(%d), rotIndex(%d), scaleIndex(%d), PPC(%f)",
2453 src.w, src.h, dst.w, dst.h, src.transform,
2454 formatIndex, rotIndex, scaleIndex, PPC);
2455 return PPC;
2456 }
2457
getAssignedCapacity()2458 float ExynosMPP::getAssignedCapacity()
2459 {
2460 float capacity = 0;
2461 float baseCycles = 0;
2462 uint32_t rotIndex = 0;
2463
2464 if (mPhysicalType != MPP_G2D)
2465 return 0;
2466
2467 /*
2468 * Client target is assigned to m2mMPP
2469 * even if capacity is not enough
2470 */
2471 if ((mAssignedDisplay != NULL) &&
2472 (mAssignedDisplay->mType == HWC_DISPLAY_VIRTUAL))
2473 return 0;
2474
2475
2476 for (uint32_t i = 0; i < mAssignedSources.size(); i++) {
2477 if ((mAssignedSources[i]->mSrcImg.transform & HAL_TRANSFORM_ROT_90) != 0)
2478 rotIndex = PPC_ROT;
2479 }
2480
2481 MPP_LOGD(eDebugCapacity, "Check all of assigned layers cycles");
2482 /* PPC of layers that were added before should be changed */
2483 /* Check cycles of all assigned layers again */
2484 if ((mAssignedDisplay != NULL) && (mMaxSrcLayerNum > 1)) {
2485 baseCycles += ((mAssignedDisplay->mXres * mAssignedDisplay->mYres) / G2D_BASE_PPC_COLORFILL);
2486 MPP_LOGD(eDebugCapacity, "colorfill cycles: %f, total cycles: %f",
2487 ((mAssignedDisplay->mXres * mAssignedDisplay->mYres) / G2D_BASE_PPC_COLORFILL), baseCycles);
2488 }
2489
2490 for (uint32_t i = 0; i < mAssignedSources.size(); i++) {
2491 float srcCycles = 0;
2492 uint32_t srcResolution = mAssignedSources[i]->mSrcImg.w * mAssignedSources[i]->mSrcImg.h;
2493 uint32_t dstResolution = mAssignedSources[i]->mMidImg.w * mAssignedSources[i]->mMidImg.h;
2494 uint32_t maxResolution = max(srcResolution, dstResolution);
2495 float PPC = 0;
2496
2497 if (mAssignedSources[i]->mSrcImg.layerFlags & EXYNOS_HWC_DIM_LAYER) {
2498 PPC = G2D_BASE_PPC_COLORFILL;
2499 } else {
2500 PPC = getPPC(mAssignedSources[i]->mSrcImg, mAssignedSources[i]->mMidImg, mAssignedSources[i]->mSrcImg,
2501 &mAssignedSources[i]->mSrcImg, &mAssignedSources[i]->mMidImg);
2502 }
2503 srcCycles = maxResolution/PPC;
2504
2505 /* Hdr and drm layer is exception */
2506 if ((hasHdrInfo(mAssignedSources[i]->mSrcImg) ||
2507 (getDrmMode(mAssignedSources[i]->mSrcImg.usageFlags) != NO_DRM))) {
2508 MPP_LOGD(eDebugCapacity, "Src[%d] is skipped(drm or hdr), cycles: %f, PPC: %f, srcResolution: %d, dstResolution: %d, rot(%d)",
2509 i, srcCycles, PPC, srcResolution, dstResolution, mAssignedSources[i]->mSrcImg.transform);
2510 continue;
2511 }
2512
2513 baseCycles += srcCycles;
2514
2515 MPP_LOGD(eDebugCapacity, "Src[%d] cycles: %f, total cycles: %f, PPC: %f, srcResolution: %d, dstResolution: %d, rot(%d)",
2516 i, srcCycles, baseCycles, PPC, srcResolution, dstResolution, mAssignedSources[i]->mSrcImg.transform);
2517 }
2518
2519 capacity = baseCycles / mClockKhz;
2520
2521 return capacity;
2522 }
2523
getRequiredCapacity(ExynosDisplay * display,struct exynos_image & src,struct exynos_image & dst)2524 float ExynosMPP::getRequiredCapacity(ExynosDisplay *display, struct exynos_image &src,
2525 struct exynos_image &dst)
2526 {
2527 float capacity = 0;
2528 float cycles = 0;
2529 if (mPhysicalType == MPP_G2D) {
2530 /* Initialize value with the cycles that were already assigned */
2531 float baseCycles = mUsedBaseCycles;
2532 float srcCycles = 0;
2533 uint32_t srcResolution = src.w * src.h;
2534 uint32_t dstResolution = dst.w * dst.h;
2535 uint32_t maxResolution = max(srcResolution, dstResolution);
2536 float curBaseCycles = 0;
2537 float PPC = 0;
2538
2539 if ((mAssignedSources.size() == 0) ||
2540 (mRotatedSrcCropBW != 0) ||
2541 ((mRotatedSrcCropBW == 0) &&
2542 ((src.transform & HAL_TRANSFORM_ROT_90) == 0))) {
2543 /* Just add cycles for current layer */
2544 if ((mAssignedSources.size() == 0) &&
2545 (display != NULL) && (mMaxSrcLayerNum > 1)) {
2546 curBaseCycles = ((display->mXres * display->mYres) / G2D_BASE_PPC_COLORFILL);
2547 MPP_LOGD(eDebugCapacity, "There is no assigned layer. Colorfill cycles: %f should be added",
2548 curBaseCycles);
2549 }
2550 curBaseCycles += getRequiredBaseCycles(src, dst);
2551 baseCycles += curBaseCycles;
2552 MPP_LOGD(eDebugCapacity, "mUsedBaseCycles was %f, Add base cycles %f, totalBaseCycle(%f)",
2553 mUsedBaseCycles, curBaseCycles, baseCycles);
2554 } else {
2555 /* Recalculate cycles for all of layers */
2556 baseCycles = 0;
2557 MPP_LOGD(eDebugCapacity, "Check all of assigned layers cycles");
2558 /* PPC of layers that were added before should be changed */
2559 /* Check cycles of all assigned layers again */
2560 if ((display != NULL) && (mMaxSrcLayerNum > 1)) {
2561 baseCycles += ((display->mXres * display->mYres) / G2D_BASE_PPC_COLORFILL);
2562 MPP_LOGD(eDebugCapacity, "colorfill cycles: %f, total cycles: %f",
2563 ((display->mXres * display->mYres) / G2D_BASE_PPC_COLORFILL), cycles);
2564 }
2565
2566 for (uint32_t i = 0; i < mAssignedSources.size(); i++) {
2567 float assignedSrcCycles = 0;
2568 uint32_t assignedSrcResolution = mAssignedSources[i]->mSrcImg.w * mAssignedSources[i]->mSrcImg.h;
2569 uint32_t assignedDstResolution = mAssignedSources[i]->mMidImg.w * mAssignedSources[i]->mMidImg.h;
2570 uint32_t assignedMaxResolution = max(assignedSrcResolution, assignedDstResolution);
2571 float assignedPPC = getPPC(mAssignedSources[i]->mSrcImg, mAssignedSources[i]->mMidImg,
2572 mAssignedSources[i]->mSrcImg, &src, &dst);
2573
2574 assignedSrcCycles = assignedMaxResolution/assignedPPC;
2575 baseCycles += assignedSrcCycles;
2576
2577 MPP_LOGD(eDebugCapacity, "Src[%d] cycles: %f, total cycles: %f, PPC: %f, srcResolution: %d, dstResolution: %d, rot(%d)",
2578 i, assignedSrcCycles, baseCycles, assignedPPC, assignedSrcResolution, assignedDstResolution, mAssignedSources[i]->mSrcImg.transform);
2579 }
2580
2581 PPC = getPPC(src, dst, src, &src, &dst);
2582
2583 srcCycles = maxResolution/PPC;
2584 baseCycles += srcCycles;
2585
2586 MPP_LOGD(eDebugCapacity, "check mppSource cycles: %f, total cycles: %f, PPC: %f, srcResolution: %d, dstResolution: %d, rot(%d)",
2587 srcCycles, baseCycles, PPC, srcResolution, dstResolution, src.transform);
2588 }
2589
2590 capacity = baseCycles / mClockKhz;
2591
2592 MPP_LOGD(eDebugCapacity, "baseCycles: %f, capacity: %f",
2593 baseCycles, capacity);
2594 } else if (mPhysicalType == MPP_MSC) {
2595 /* Initialize value with the capacity that were already assigned */
2596 capacity = mUsedCapacity;
2597
2598 /* Just add capacity for current layer */
2599 float srcPPC = getPPC(src, dst, src);
2600 float dstPPC = getPPC(src, dst, dst);
2601 float srcCapacity = (float((src.w * src.h))) / (mClockKhz * srcPPC);
2602 float dstCapacity = (float((dst.w * dst.h))) / (mClockKhz * dstPPC);
2603
2604 capacity += max(srcCapacity, dstCapacity);
2605
2606 }
2607
2608 return capacity;
2609 }
2610
getRequiredBaseCycles(struct exynos_image & src,struct exynos_image & dst)2611 float ExynosMPP::getRequiredBaseCycles(struct exynos_image &src, struct exynos_image &dst)
2612 {
2613 if (mPhysicalType != MPP_G2D)
2614 return 0;
2615
2616 uint32_t srcResolution = src.w * src.h;
2617 uint32_t dstResolution = dst.w * dst.h;
2618 uint32_t maxResolution = max(srcResolution, dstResolution);
2619
2620 return maxResolution/(float)getPPC(src, dst, src);
2621 }
2622
addCapacity(ExynosMPPSource * mppSource)2623 bool ExynosMPP::addCapacity(ExynosMPPSource* mppSource)
2624 {
2625 if ((mppSource == NULL) || mCapacity == -1)
2626 return false;
2627
2628 if (mPhysicalType == MPP_G2D) {
2629 bool needUpdateCapacity = true;
2630 if ((mAssignedSources.size() == 0) ||
2631 (mRotatedSrcCropBW != 0) ||
2632 ((mRotatedSrcCropBW == 0) &&
2633 ((mppSource->mSrcImg.transform & HAL_TRANSFORM_ROT_90) == 0))) {
2634 needUpdateCapacity = false;
2635 }
2636
2637 if (needUpdateCapacity)
2638 return true;
2639
2640 if ((mMaxSrcLayerNum > 1) &&
2641 (mAssignedSources.size() == 0)) {
2642 if (mAssignedDisplay != NULL) {
2643 /* This will be the first mppSource that is assigned to the ExynosMPP */
2644 /* Add capacity for background */
2645 mUsedBaseCycles += ((mAssignedDisplay->mXres * mAssignedDisplay->mYres) / G2D_BASE_PPC_COLORFILL);
2646 MPP_LOGD(eDebugCapacity, "\tcolorfill cycles: %f, total cycles: %f",
2647 ((mAssignedDisplay->mXres * mAssignedDisplay->mYres) / G2D_BASE_PPC_COLORFILL), mUsedBaseCycles);
2648 } else {
2649 MPP_LOGE("mAssignedDisplay is null");
2650 }
2651 }
2652
2653 float baseCycles = getRequiredBaseCycles(mppSource->mSrcImg, mppSource->mMidImg);
2654 mUsedBaseCycles += baseCycles;
2655
2656 uint32_t srcResolution = mppSource->mSrcImg.w * mppSource->mSrcImg.h;
2657 uint32_t dstResolution = mppSource->mMidImg.w * mppSource->mMidImg.h;
2658 if ((mppSource->mSrcImg.transform & HAL_TRANSFORM_ROT_90) == 0)
2659 mNoRotatedSrcCropBW += srcResolution;
2660 else
2661 mRotatedSrcCropBW += srcResolution;
2662
2663 mUsedCapacity = mUsedBaseCycles / mClockKhz;
2664
2665 MPP_LOGD(eDebugCapacity, "src num: %zu base cycle is added: %f, mUsedBaseCycles: %f, mUsedCapacity(%f), srcResolution: %d, dstResolution: %d, rot: %d, mNoRotatedSrcCropBW(%d), mRotatedSrcCropBW(%d)",
2666 mAssignedSources.size(),
2667 baseCycles, mUsedBaseCycles, mUsedCapacity, srcResolution, dstResolution,
2668 mppSource->mSrcImg.transform, mNoRotatedSrcCropBW, mRotatedSrcCropBW);
2669 } else if (mPhysicalType == MPP_MSC) {
2670 mUsedCapacity = getRequiredCapacity(NULL, mppSource->mSrcImg, mppSource->mMidImg);
2671 }
2672
2673 return false;
2674 }
2675
removeCapacity(ExynosMPPSource * mppSource)2676 bool ExynosMPP::removeCapacity(ExynosMPPSource* mppSource)
2677 {
2678 if ((mppSource == NULL) || (mCapacity == -1))
2679 return false;
2680
2681 if (mPhysicalType == MPP_G2D) {
2682 uint32_t srcResolution = mppSource->mSrcImg.w * mppSource->mSrcImg.h;
2683 uint32_t dstResolution = mppSource->mDstImg.w * mppSource->mDstImg.h;
2684
2685 uint32_t prevRotatedSrcCropBW = mRotatedSrcCropBW;
2686
2687 if (mppSource->mSrcImg.transform == 0)
2688 mNoRotatedSrcCropBW -= srcResolution;
2689 else
2690 mRotatedSrcCropBW -= srcResolution;
2691
2692 if ((prevRotatedSrcCropBW > 0) && (mRotatedSrcCropBW == 0))
2693 return true;
2694
2695 float baseCycles = getRequiredBaseCycles(mppSource->mSrcImg, mppSource->mMidImg);
2696 mUsedBaseCycles -= baseCycles;
2697
2698 mUsedCapacity = mUsedBaseCycles / mClockKhz;
2699
2700 MPP_LOGD(eDebugCapacity, "src num: %zu, base cycle is removed: %f, mUsedBaseCycles: %f, mUsedCapacity(%f), srcResolution: %d, dstResolution: %d, rot: %d, mNoRotatedSrcCropBW(%d), mRotatedSrcCropBW(%d)",
2701 mAssignedSources.size(),
2702 baseCycles, mUsedBaseCycles, mUsedCapacity, srcResolution, dstResolution,
2703 mppSource->mSrcImg.transform, mNoRotatedSrcCropBW, mRotatedSrcCropBW);
2704 } else if (mPhysicalType == MPP_MSC) {
2705 exynos_image &src = mppSource->mSrcImg;
2706 exynos_image &dst = mppSource->mDstImg;
2707 uint32_t srcResolution = src.w * src.h;
2708 uint32_t dstResolution = dst.w * dst.h;
2709
2710 float srcCapacity = (float)srcResolution / getPPC(src, dst, src);
2711 float dstCapacity = (float)dstResolution / getPPC(src, dst, dst);
2712
2713 mUsedCapacity -= max(srcCapacity, dstCapacity);
2714 }
2715
2716 return false;
2717 }
2718
resetUsedCapacity()2719 void ExynosMPP::resetUsedCapacity()
2720 {
2721 mUsedCapacity = 0;
2722 mUsedBaseCycles = 0;
2723 mRotatedSrcCropBW = 0;
2724 mNoRotatedSrcCropBW = 0;
2725 }
2726
updateUsedCapacity()2727 int32_t ExynosMPP::updateUsedCapacity()
2728 {
2729 int32_t ret = NO_ERROR;
2730 if (mCapacity == -1)
2731 return ret;
2732
2733 float capacity = 0;
2734 mUsedCapacity = 0;
2735
2736 mRotatedSrcCropBW = 0;
2737 mNoRotatedSrcCropBW = 0;
2738
2739 if ((mPhysicalType == MPP_G2D) &&
2740 (mAssignedDisplay != NULL) &&
2741 (mAssignedSources.size() > 0)) {
2742 float cycles = 0;
2743
2744 if (mMaxSrcLayerNum > 1) {
2745 cycles += ((mAssignedDisplay->mXres * mAssignedDisplay->mYres) / G2D_BASE_PPC_COLORFILL);
2746 MPP_LOGD(eDebugCapacity, "\tcolorfill cycles: %f, total cycles: %f",
2747 ((mAssignedDisplay->mXres * mAssignedDisplay->mYres) / G2D_BASE_PPC_COLORFILL), cycles);
2748 }
2749 for (uint32_t i = 0; i < mAssignedSources.size(); i++) {
2750 uint32_t srcResolution = mAssignedSources[i]->mSrcImg.w * mAssignedSources[i]->mSrcImg.h;
2751 if ((mAssignedSources[i]->mSrcImg.transform & HAL_TRANSFORM_ROT_90) == 0)
2752 mNoRotatedSrcCropBW += srcResolution;
2753 else
2754 mRotatedSrcCropBW += srcResolution;
2755 }
2756 MPP_LOGD(eDebugCapacity, "mNoRotatedSrcCropBW(%d), mRotatedSrcCropBW(%d)",
2757 mNoRotatedSrcCropBW, mRotatedSrcCropBW);
2758 for (uint32_t i = 0; i < mAssignedSources.size(); i++) {
2759 float srcCycles = 0;
2760 uint32_t srcResolution = mAssignedSources[i]->mSrcImg.w * mAssignedSources[i]->mSrcImg.h;
2761 uint32_t dstResolution = mAssignedSources[i]->mMidImg.w * mAssignedSources[i]->mMidImg.h;
2762 uint32_t maxResolution = max(srcResolution, dstResolution);
2763 float PPC = getPPC(mAssignedSources[i]->mSrcImg, mAssignedSources[i]->mMidImg, mAssignedSources[i]->mSrcImg);
2764 srcCycles = maxResolution/PPC;
2765 cycles += srcCycles;
2766
2767 MPP_LOGD(eDebugCapacity, "Src[%d] cycles: %f, total cycles: %f, PPC: %f, srcResolution: %d, dstResolution: %d, rot(%d)",
2768 i, srcCycles, cycles, PPC, srcResolution, dstResolution, mAssignedSources[i]->mSrcImg.transform);
2769 }
2770
2771 mUsedBaseCycles = cycles;
2772 capacity = cycles / mClockKhz;
2773
2774 mUsedCapacity = capacity;
2775
2776 }
2777 MPP_LOGD(eDebugCapacity, "assigned layer size(%zu), mUsedCapacity: %f", mAssignedSources.size(), mUsedCapacity);
2778
2779 return mUsedCapacity;
2780 }
2781
getRestrictionClassification(const struct exynos_image & img) const2782 uint32_t ExynosMPP::getRestrictionClassification(const struct exynos_image &img) const {
2783 return !!(isFormatRgb(img.format) == false);
2784 }
2785
prioritize(int priority)2786 int ExynosMPP::prioritize(int priority)
2787 {
2788 if ((mPhysicalType != MPP_G2D) ||
2789 (mAcrylicHandle == NULL)) {
2790 MPP_LOGE("invalid function call");
2791 return -1;
2792 }
2793 int ret = NO_ERROR;
2794 ret = mAcrylicHandle->prioritize(priority);
2795
2796 if ((priority > 0) && (ret == 1))
2797 {
2798 /* G2D Driver returned EBUSY */
2799 mHWBusyFlag = true;
2800 }
2801 MPP_LOGD(eDebugMPP, "set resource prioritize (%d), ret(%d), mHWBusyFlag(%d)", priority, ret, mHWBusyFlag);
2802
2803 return ret;
2804 }
2805
increaseDstBuffIndex()2806 uint32_t ExynosMPP::increaseDstBuffIndex()
2807 {
2808 if (mAllocOutBufFlag)
2809 mCurrentDstBuf = (mCurrentDstBuf + 1) % NUM_MPP_DST_BUFS(mLogicalType);
2810 return mCurrentDstBuf;
2811 }
2812
reloadResourceForHWFC()2813 void ExynosMPP::reloadResourceForHWFC()
2814 {
2815 ALOGI("reloadResourceForHWFC()");
2816 delete mAcrylicHandle;
2817 mAcrylicHandle = AcrylicFactory::createAcrylic("default_compositor");
2818 if (mAcrylicHandle == NULL) {
2819 MPP_LOGE("Fail to allocate compositor");
2820 } else {
2821 mAcrylicHandle->setDefaultColor(0, 0, 0, 0);
2822 MPP_LOGI("The resource is reloaded for HWFC: %p", mAcrylicHandle);
2823 }
2824 for (uint32_t i = 0; i < NUM_MPP_SRC_BUFS; i++)
2825 {
2826 if (mSrcImgs[i].mppLayer != NULL) {
2827 delete mSrcImgs[i].mppLayer;
2828 mSrcImgs[i].mppLayer = NULL;
2829 }
2830 }
2831 }
2832
setTargetDisplayLuminance(uint16_t min,uint16_t max)2833 void ExynosMPP::setTargetDisplayLuminance(uint16_t min, uint16_t max)
2834 {
2835 MPP_LOGD(eDebugMPP, "%s: min(%d), max(%d)", __func__, min, max);
2836 if (mAcrylicHandle == NULL) {
2837 MPP_LOGE("mAcrylicHandle is NULL");
2838 } else
2839 mAcrylicHandle->setTargetDisplayLuminance(min, max);
2840 }
2841
setTargetDisplayDevice(int device)2842 void ExynosMPP::setTargetDisplayDevice(int device)
2843 {
2844 ALOGI("%s: device(%d)", __func__, device);
2845 if (mAcrylicHandle == NULL) {
2846 MPP_LOGE("mAcrylicHandle is NULL");
2847 } else
2848 mAcrylicHandle->setTargetDisplayInfo(&device);
2849 }
2850
dump(String8 & result)2851 void ExynosMPP::dump(String8& result)
2852 {
2853 int32_t assignedDisplayType = -1;
2854 if (mAssignedDisplay != NULL)
2855 assignedDisplayType = mAssignedDisplay->mType;
2856
2857 result.appendFormat("%s: types mppType(%d), (p:%d, l:0x%2x), indexs(p:%d, l:%d), preAssignDisplay(0x%2x)\n",
2858 mName.string(), mMPPType, mPhysicalType, mLogicalType, mPhysicalIndex, mLogicalIndex, mPreAssignDisplayInfo);
2859 result.appendFormat("\tEnable: %d, HWState: %d, AssignedState: %d, assignedDisplay(%d)\n",
2860 mEnable, mHWState, mAssignedState, assignedDisplayType);
2861 result.appendFormat("\tPrevAssignedState: %d, PrevAssignedDisplayType: %d, ReservedDisplay: %d\n",
2862 mPrevAssignedState, mPrevAssignedDisplayType, mReservedDisplay);
2863 result.appendFormat("\tassinedSourceNum(%zu), Capacity(%f), CapaUsed(%f), mCurrentDstBuf(%d)\n",
2864 mAssignedSources.size(), mCapacity, mUsedCapacity, mCurrentDstBuf);
2865
2866 }
2867
closeFences()2868 void ExynosMPP::closeFences()
2869 {
2870 for (uint32_t i = 0; i < mAssignedSources.size(); i++)
2871 {
2872 mSrcImgs[i].acrylicAcquireFenceFd =
2873 fence_close(mSrcImgs[i].acrylicAcquireFenceFd, mAssignedDisplay,
2874 FENCE_TYPE_SRC_ACQUIRE, FENCE_IP_G2D);
2875 mSrcImgs[i].acrylicReleaseFenceFd =
2876 fence_close(mSrcImgs[i].acrylicReleaseFenceFd, mAssignedDisplay,
2877 FENCE_TYPE_SRC_RELEASE, FENCE_IP_G2D);
2878 }
2879
2880 mDstImgs[mCurrentDstBuf].acrylicAcquireFenceFd =
2881 fence_close(mDstImgs[mCurrentDstBuf].acrylicAcquireFenceFd, mAssignedDisplay,
2882 FENCE_TYPE_DST_ACQUIRE, FENCE_IP_G2D);
2883 mDstImgs[mCurrentDstBuf].acrylicReleaseFenceFd =
2884 fence_close(mDstImgs[mCurrentDstBuf].acrylicReleaseFenceFd, mAssignedDisplay,
2885 FENCE_TYPE_DST_RELEASE, FENCE_IP_G2D);
2886 }
2887
updateAttr()2888 void ExynosMPP::updateAttr()
2889 {
2890 MPP_LOGD(eDebugAttrSetting, "updateAttr::mPhysicalType(%d), mAttr(0x%" PRIx64 ")",
2891 mPhysicalType, mAttr);
2892
2893 if (mResourceManager == NULL) return;
2894
2895 auto iter = mResourceManager->mMPPAttrs.find(mPhysicalType);
2896 if (iter != mResourceManager->mMPPAttrs.end()) {
2897 mAttr = iter->second;
2898 MPP_LOGD(eDebugAttrSetting, "After mAttr(0x%" PRIx64 ")", mAttr);
2899 }
2900 }
2901
2902