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 
21 #define ATRACE_TAG (ATRACE_TAG_GRAPHICS | ATRACE_TAG_HAL)
22 #include "ExynosResourceManager.h"
23 
24 #include <cutils/properties.h>
25 
26 #include <numeric>
27 #include <unordered_set>
28 
29 #include "ExynosDeviceInterface.h"
30 #include "ExynosExternalDisplay.h"
31 #include "ExynosHWCDebug.h"
32 #include "ExynosLayer.h"
33 #include "ExynosMPPModule.h"
34 #include "ExynosPrimaryDisplayModule.h"
35 #include "ExynosVirtualDisplay.h"
36 #include "hardware/exynos/acryl.h"
37 
38 using namespace std::chrono_literals;
39 constexpr float msecsPerSec = std::chrono::milliseconds(1s).count();
40 
41 #ifndef USE_MODULE_ATTR
42 /* Basic supported features */
43 feature_support_t feature_table[] =
44 {
45     {MPP_DPP_G,
46         MPP_ATTR_BLOCK_MODE | MPP_ATTR_WINDOW_UPDATE | MPP_ATTR_DIM
47     },
48 
49     {MPP_DPP_GF,
50         MPP_ATTR_AFBC | MPP_ATTR_BLOCK_MODE | MPP_ATTR_WINDOW_UPDATE | MPP_ATTR_DIM
51     },
52 
53     {MPP_DPP_VG,
54         MPP_ATTR_BLOCK_MODE | MPP_ATTR_WINDOW_UPDATE | MPP_ATTR_DIM
55     },
56 
57     {MPP_DPP_VGS,
58         MPP_ATTR_BLOCK_MODE | MPP_ATTR_WINDOW_UPDATE | MPP_ATTR_SCALE | MPP_ATTR_DIM
59     },
60 
61     {MPP_DPP_VGF,
62         MPP_ATTR_AFBC | MPP_ATTR_BLOCK_MODE | MPP_ATTR_WINDOW_UPDATE | MPP_ATTR_DIM
63     },
64 
65     {MPP_DPP_VGFS,
66         MPP_ATTR_AFBC | MPP_ATTR_BLOCK_MODE | MPP_ATTR_WINDOW_UPDATE | MPP_ATTR_SCALE | MPP_ATTR_DIM
67     },
68 
69     {MPP_DPP_VGRFS,
70         MPP_ATTR_AFBC | MPP_ATTR_BLOCK_MODE | MPP_ATTR_WINDOW_UPDATE | MPP_ATTR_SCALE |
71         MPP_ATTR_FLIP_H | MPP_ATTR_FLIP_V | MPP_ATTR_ROT_90 |
72         MPP_ATTR_DIM | MPP_ATTR_HDR10
73     },
74 
75     {MPP_MSC,
76         MPP_ATTR_FLIP_H | MPP_ATTR_FLIP_V | MPP_ATTR_ROT_90
77     },
78 
79     {MPP_G2D,
80         MPP_ATTR_AFBC | MPP_ATTR_FLIP_H | MPP_ATTR_FLIP_V | MPP_ATTR_ROT_90 |
81         MPP_ATTR_HDR10 | MPP_ATTR_USE_CAPA
82     }
83 };
84 #endif
85 
86 using namespace android;
87 using namespace vendor::graphics;
88 using namespace SOC_VERSION;
89 
90 ExynosMPPVector ExynosResourceManager::mOtfMPPs;
91 ExynosMPPVector ExynosResourceManager::mM2mMPPs;
92 extern struct exynos_hwc_control exynosHWCControl;
93 
ExynosMPPVector()94 ExynosMPPVector::ExynosMPPVector() {
95 }
96 
ExynosMPPVector(const ExynosMPPVector & rhs)97 ExynosMPPVector::ExynosMPPVector(const ExynosMPPVector& rhs)
98     : android::SortedVector<ExynosMPP* >(rhs) {
99 }
100 
do_compare(const void * lhs,const void * rhs) const101 int ExynosMPPVector::do_compare(const void* lhs, const void* rhs) const
102 {
103     if (lhs == NULL || rhs == NULL)
104         return 0;
105 
106     const ExynosMPP* l = *((ExynosMPP**)(lhs));
107     const ExynosMPP* r = *((ExynosMPP**)(rhs));
108 
109     if (l == NULL || r == NULL)
110         return 0;
111 
112     if (l->mPhysicalType != r->mPhysicalType) {
113         return l->mPhysicalType - r->mPhysicalType;
114     }
115 
116     if (l->mLogicalType != r->mLogicalType) {
117         return l->mLogicalType - r->mLogicalType;
118     }
119 
120     if (l->mPhysicalIndex != r->mPhysicalIndex) {
121         return l->mPhysicalIndex - r->mPhysicalIndex;
122     }
123 
124     return l->mLogicalIndex - r->mLogicalIndex;
125 }
126 /**
127  * ExynosResourceManager implementation
128  *
129  */
130 
DstBufMgrThread(ExynosResourceManager * exynosResourceManager)131 ExynosResourceManager::DstBufMgrThread::DstBufMgrThread(ExynosResourceManager *exynosResourceManager)
132 : mExynosResourceManager(exynosResourceManager),
133     mRunning(false),
134     mBufXres(0),
135     mBufYres(0)
136 {
137 }
138 
~DstBufMgrThread()139 ExynosResourceManager::DstBufMgrThread::~DstBufMgrThread()
140 {
141 }
142 
143 
ExynosResourceManager(ExynosDevice * device)144 ExynosResourceManager::ExynosResourceManager(ExynosDevice *device)
145 : mForceReallocState(DST_REALLOC_DONE),
146     mDevice(device),
147     hasHdrLayer(false),
148     hasDrmLayer(false),
149     mFormatRestrictionCnt(0),
150     mDstBufMgrThread(sp<DstBufMgrThread>::make(this)),
151     mResourceReserved(0x0)
152 {
153 
154     memset(mSizeRestrictionCnt, 0, sizeof(mSizeRestrictionCnt));
155     memset(mFormatRestrictions, 0, sizeof(mFormatRestrictions));
156     memset(mSizeRestrictions, 0, sizeof(mSizeRestrictions));
157 
158     size_t num_mpp_units = sizeof(AVAILABLE_OTF_MPP_UNITS)/sizeof(exynos_mpp_t);
159     for (size_t i = 0; i < num_mpp_units; i++) {
160         exynos_mpp_t exynos_mpp = AVAILABLE_OTF_MPP_UNITS[i];
161         ALOGI("otfMPP type(%d, %d), physical_index(%d), logical_index(%d)",
162                 exynos_mpp.physicalType, exynos_mpp.logicalType,
163                 exynos_mpp.physical_index, exynos_mpp.logical_index);
164         ExynosMPP* exynosMPP = new ExynosMPPModule(this, exynos_mpp.physicalType,
165                 exynos_mpp.logicalType, exynos_mpp.name, exynos_mpp.physical_index,
166                 exynos_mpp.logical_index, exynos_mpp.pre_assign_info);
167         exynosMPP->mMPPType = MPP_TYPE_OTF;
168         mOtfMPPs.add(exynosMPP);
169     }
170 
171     num_mpp_units = sizeof(AVAILABLE_M2M_MPP_UNITS)/sizeof(exynos_mpp_t);
172     for (size_t i = 0; i < num_mpp_units; i++) {
173         exynos_mpp_t exynos_mpp = AVAILABLE_M2M_MPP_UNITS[i];
174         ALOGI("m2mMPP type(%d, %d), physical_index(%d), logical_index(%d)",
175                 exynos_mpp.physicalType, exynos_mpp.logicalType,
176                 exynos_mpp.physical_index, exynos_mpp.logical_index);
177         ExynosMPP* exynosMPP = new ExynosMPPModule(this, exynos_mpp.physicalType,
178                 exynos_mpp.logicalType, exynos_mpp.name, exynos_mpp.physical_index,
179                 exynos_mpp.logical_index, exynos_mpp.pre_assign_info);
180         exynosMPP->mMPPType = MPP_TYPE_M2M;
181         mM2mMPPs.add(exynosMPP);
182     }
183 
184     ALOGI("mOtfMPPs(%zu), mM2mMPPs(%zu)", mOtfMPPs.size(), mM2mMPPs.size());
185     if (hwcCheckDebugMessages(eDebugResourceManager)) {
186         for (uint32_t i = 0; i < mOtfMPPs.size(); i++)
187         {
188             HDEBUGLOGD(eDebugResourceManager, "otfMPP[%d]", i);
189             String8 dumpMPP;
190             mOtfMPPs[i]->dump(dumpMPP);
191             HDEBUGLOGD(eDebugResourceManager, "%s", dumpMPP.string());
192         }
193         for (uint32_t i = 0; i < mM2mMPPs.size(); i++)
194         {
195             HDEBUGLOGD(eDebugResourceManager, "m2mMPP[%d]", i);
196             String8 dumpMPP;
197             mM2mMPPs[i]->dump(dumpMPP);
198             HDEBUGLOGD(eDebugResourceManager, "%s", dumpMPP.string());
199         }
200     }
201 
202     mDstBufMgrThread->mRunning = true;
203     mDstBufMgrThread->run("DstBufMgrThread");
204 }
205 
~ExynosResourceManager()206 ExynosResourceManager::~ExynosResourceManager()
207 {
208     for (int32_t i = mOtfMPPs.size(); i-- > 0;) {
209         ExynosMPP *exynosMPP = mOtfMPPs[i];
210         delete exynosMPP;
211     }
212     mOtfMPPs.clear();
213     for (int32_t i = mM2mMPPs.size(); i-- > 0;) {
214         ExynosMPP *exynosMPP = mM2mMPPs[i];
215         delete exynosMPP;
216     }
217     mM2mMPPs.clear();
218 
219     mDstBufMgrThread->mRunning = false;
220     mDstBufMgrThread->requestExitAndWait();
221 }
222 
reloadResourceForHWFC()223 void ExynosResourceManager::reloadResourceForHWFC()
224 {
225     for (int32_t i = mM2mMPPs.size(); i-- > 0;) {
226         ExynosMPP *exynosMPP = mM2mMPPs[i];
227         if (exynosMPP->mLogicalType == MPP_LOGICAL_G2D_COMBO &&
228                 (exynosMPP->mPreAssignDisplayInfo & HWC_DISPLAY_VIRTUAL_BIT)) {
229             exynosMPP->reloadResourceForHWFC();
230             break;
231         }
232     }
233 }
234 
setTargetDisplayLuminance(uint16_t min,uint16_t max)235 void ExynosResourceManager::setTargetDisplayLuminance(uint16_t min, uint16_t max)
236 {
237     for (int32_t i = mM2mMPPs.size(); i-- > 0;) {
238         ExynosMPP *exynosMPP = mM2mMPPs[i];
239         if (exynosMPP->mLogicalType == MPP_LOGICAL_G2D_COMBO &&
240                 (exynosMPP->mPreAssignDisplayInfo & HWC_DISPLAY_VIRTUAL_BIT)) {
241             exynosMPP->setTargetDisplayLuminance(min, max);
242             break;
243         }
244     }
245 }
246 
setTargetDisplayDevice(int device)247 void ExynosResourceManager::setTargetDisplayDevice(int device)
248 {
249     for (int32_t i = mM2mMPPs.size(); i-- > 0;) {
250         ExynosMPP *exynosMPP = mM2mMPPs[i];
251         if (exynosMPP->mLogicalType == MPP_LOGICAL_G2D_COMBO &&
252                 (exynosMPP->mPreAssignDisplayInfo & HWC_DISPLAY_VIRTUAL_BIT)) {
253             exynosMPP->setTargetDisplayDevice(device);
254             break;
255         }
256     }
257 }
258 
doPreProcessing()259 int32_t ExynosResourceManager::doPreProcessing()
260 {
261     int32_t ret = NO_ERROR;
262     /* Assign m2mMPP's out buffers */
263     ExynosDisplay *display = mDevice->getDisplay(getDisplayId(HWC_DISPLAY_PRIMARY, 0));
264     if (display == NULL)
265         return -EINVAL;
266     ret = doAllocDstBufs(display->mXres, display->mYres);
267     return ret;
268 }
269 
doReallocDstBufs(uint32_t Xres,uint32_t Yres)270 void ExynosResourceManager::doReallocDstBufs(uint32_t Xres, uint32_t Yres)
271 {
272     HDEBUGLOGD(eDebugBuf, "M2M dst alloc call ");
273     mDstBufMgrThread->reallocDstBufs(Xres, Yres);
274 }
275 
needDstRealloc(uint32_t Xres,uint32_t Yres,ExynosMPP * m2mMPP)276 bool ExynosResourceManager::DstBufMgrThread::needDstRealloc(uint32_t Xres, uint32_t Yres, ExynosMPP *m2mMPP)
277 {
278     bool ret = false;
279     if (((Xres == 720 && Yres == 1480) && (m2mMPP->getDstAllocSize() != DST_SIZE_HD_PLUS)) ||
280             ((Xres == 720 && Yres == 1280) && (m2mMPP->getDstAllocSize() != DST_SIZE_HD)) ||
281             ((Xres == 1080 && Yres == 2220) && (m2mMPP->getDstAllocSize() != DST_SIZE_FHD_PLUS)) ||
282             ((Xres == 1080 && Yres == 1920) && (m2mMPP->getDstAllocSize() != DST_SIZE_FHD)) ||
283             ((Xres == 1440 && Yres == 2960) && (m2mMPP->getDstAllocSize() != DST_SIZE_WQHD_PLUS)) ||
284             ((Xres == 1440 && Yres == 2560) && (m2mMPP->getDstAllocSize() != DST_SIZE_WQHD))) {
285         ret = true;
286     }
287     return ret;
288 }
289 
reallocDstBufs(uint32_t Xres,uint32_t Yres)290 void ExynosResourceManager::DstBufMgrThread::reallocDstBufs(uint32_t Xres, uint32_t Yres)
291 {
292     bool needRealloc = false;
293     for (uint32_t i = 0; i < mM2mMPPs.size(); i++) {
294         if (mM2mMPPs[i]->needPreAllocation())
295         {
296             if (needDstRealloc(Xres, Yres, mM2mMPPs[i])) {
297                 HDEBUGLOGD(eDebugBuf, "M2M dst alloc : %d Realloc Start ++++++", mM2mMPPs[i]->mLogicalType);
298                 needRealloc = true;
299             }
300             else HDEBUGLOGD(eDebugBuf, "M2M dst alloc : %d MPP's DST Realloc is not needed : Size is same", mM2mMPPs[i]->mLogicalType);
301         }
302     }
303 
304     if (needRealloc) {
305         Mutex::Autolock lock(mStateMutex);
306         if (mExynosResourceManager->mForceReallocState == DST_REALLOC_DONE) {
307             mExynosResourceManager->mForceReallocState = DST_REALLOC_START;
308             android::Mutex::Autolock lock(mMutex);
309             mCondition.signal();
310         } else {
311             HDEBUGLOGD(eDebugBuf, "M2M dst alloc thread : queue aready.");
312         }
313     }
314 }
315 
threadLoop()316 bool ExynosResourceManager::DstBufMgrThread::threadLoop()
317 {
318     while(mRunning) {
319         Mutex::Autolock lock(mMutex);
320         mCondition.wait(mMutex);
321 
322         ExynosDevice *device = mExynosResourceManager->mDevice;
323         if (device == NULL)
324             return false;
325         ExynosDisplay *display = device->getDisplay(getDisplayId(HWC_DISPLAY_PRIMARY, 0));
326         if (display == NULL)
327             return false;
328 
329         do {
330             {
331                 HDEBUGLOGD(eDebugBuf, "M2M dst alloc %d, %d, %d, %d : Realloc On going ----------",
332                         mBufXres, display->mXres, mBufYres, display->mYres);
333                 Mutex::Autolock lock(mResInfoMutex);
334                 mBufXres = display->mXres;mBufYres = display->mYres;
335             }
336             mExynosResourceManager->doAllocDstBufs(mBufXres, mBufYres);
337         } while (mBufXres != display->mXres || mBufYres != display->mYres);
338 
339         {
340             Mutex::Autolock lock(mStateMutex);
341             mExynosResourceManager->mForceReallocState = DST_REALLOC_DONE;
342             HDEBUGLOGD(eDebugBuf, "M2M dst alloc %d, %d, %d, %d : Realloc On Done ----------",
343                     mBufXres, display->mXres, mBufYres, display->mYres);
344         }
345     }
346     return true;
347 }
348 
doAllocDstBufs(uint32_t Xres,uint32_t Yres)349 int32_t ExynosResourceManager::doAllocDstBufs(uint32_t Xres, uint32_t Yres)
350 {
351     ATRACE_CALL();
352     int32_t ret = NO_ERROR;
353     /* Assign m2mMPP's out buffers */
354 
355     for (uint32_t i = 0; i < mM2mMPPs.size(); i++) {
356         if (mM2mMPPs[i]->needPreAllocation())
357         {
358             mM2mMPPs[i]->mFreeOutBufFlag = false;
359             for (uint32_t index = 0; index < NUM_MPP_DST_BUFS(mM2mMPPs[i]->mLogicalType); index++) {
360                 HDEBUGLOGD(eDebugBuf, "%s allocate dst buffer[%d]%p, x: %d, y: %d",
361                         __func__, index, mM2mMPPs[i]->mDstImgs[index].bufferHandle, Xres, Yres);
362                 uint32_t bufAlign = mM2mMPPs[i]->getOutBufAlign();
363                 ret = mM2mMPPs[i]->allocOutBuf(ALIGN_UP(Xres, bufAlign),
364                         ALIGN_UP(Yres, bufAlign),
365                         DEFAULT_MPP_DST_FORMAT, 0x0, index);
366                 if (ret < 0) {
367                     HWC_LOGE(NULL, "%s:: fail to allocate dst buffer[%d]",
368                             __func__, index);
369                     return ret;
370                 }
371                 mM2mMPPs[i]->mPrevAssignedDisplayType = HWC_DISPLAY_PRIMARY;
372             }
373             mM2mMPPs[i]->setDstAllocSize(Xres, Yres);
374         }
375     }
376     return ret;
377 }
378 
checkScenario(ExynosDisplay __unused * display)379 int32_t ExynosResourceManager::checkScenario(ExynosDisplay __unused *display)
380 {
381     uint32_t prevResourceReserved = mResourceReserved;
382     mResourceReserved = 0x0;
383     /* Check whether camera preview is running */
384     ExynosDisplay *exynosDisplay = NULL;
385     for (uint32_t i = 0; i < mDevice->mDisplays.size(); i++) {
386         exynosDisplay = mDevice->mDisplays[i];
387         if ((exynosDisplay != NULL) && (exynosDisplay->mPlugState == true)) {
388             for (uint32_t i = 0; i < exynosDisplay->mLayers.size(); i++) {
389                 ExynosLayer *layer = exynosDisplay->mLayers[i];
390                 VendorGraphicBufferMeta gmeta(layer->mLayerBuffer);
391                 if ((layer->mLayerBuffer != NULL) &&
392                     (gmeta.producer_usage & BufferUsage::CAMERA_OUTPUT)) {
393                     mResourceReserved |= (MPP_LOGICAL_G2D_YUV | MPP_LOGICAL_G2D_RGB);
394                     break;
395                 }
396             }
397         }
398     }
399 
400     char value[PROPERTY_VALUE_MAX];
401     bool preview;
402     property_get("persist.vendor.sys.camera.preview", value, "0");
403     preview = !!atoi(value);
404     if (preview)
405         mResourceReserved |= (MPP_LOGICAL_G2D_YUV | MPP_LOGICAL_G2D_RGB);
406 
407     if (prevResourceReserved != mResourceReserved) {
408         mDevice->setGeometryChanged(GEOMETRY_DEVICE_SCENARIO_CHANGED);
409     }
410 
411     return NO_ERROR;
412 }
413 
414 /**
415  * @param * display
416  * @return int
417  */
assignResource(ExynosDisplay * display)418 int32_t ExynosResourceManager::assignResource(ExynosDisplay *display)
419 {
420     ATRACE_CALL();
421     int ret = 0;
422     if ((mDevice == NULL) || (display == NULL))
423         return -EINVAL;
424 
425     HDEBUGLOGD(eDebugResourceManager|eDebugSkipResourceAssign, "mGeometryChanged(0x%" PRIx64 "), display(%d)",
426             mDevice->mGeometryChanged, display->mType);
427 
428     if (mDevice->mGeometryChanged == 0) {
429         return NO_ERROR;
430     }
431 
432     for (uint32_t i = 0; i < display->mLayers.size(); i++) {
433         display->mLayers[i]->resetValidateData();
434     }
435 
436     display->initializeValidateInfos();
437 
438     if ((ret = preProcessLayer(display)) != NO_ERROR) {
439         HWC_LOGE(display, "%s:: preProcessLayer() error (%d)",
440                 __func__, ret);
441         return ret;
442     }
443 
444     if (mDevice->isFirstValidate()) {
445         HDEBUGLOGD(eDebugResourceManager, "This is first validate");
446         if (exynosHWCControl.displayMode < DISPLAY_MODE_NUM)
447             mDevice->mDisplayMode = exynosHWCControl.displayMode;
448 
449         if ((ret = prepareResources()) != NO_ERROR) {
450             HWC_LOGE(display, "%s:: prepareResources() error (%d)",
451                     __func__, ret);
452             return ret;
453         }
454         preAssignWindows();
455 
456     }
457 
458     if ((ret = updateSupportedMPPFlag(display)) != NO_ERROR) {
459         HWC_LOGE(display, "%s:: updateSupportedMPPFlag() error (%d)",
460                 __func__, ret);
461         return ret;
462     }
463 
464     if ((ret = assignResourceInternal(display)) != NO_ERROR) {
465         HWC_LOGE(display, "%s:: assignResourceInternal() error (%d)",
466                 __func__, ret);
467         return ret;
468     }
469 
470     if ((ret = assignWindow(display)) != NO_ERROR) {
471         HWC_LOGE(display, "%s:: assignWindow() error (%d)",
472                 __func__, ret);
473         return ret;
474     }
475 
476     if (hwcCheckDebugMessages(eDebugResourceManager)) {
477         HDEBUGLOGD(eDebugResourceManager, "AssignResource result");
478         String8 result;
479         display->mClientCompositionInfo.dump(result);
480         HDEBUGLOGD(eDebugResourceManager, "%s", result.string());
481         result.clear();
482         display->mExynosCompositionInfo.dump(result);
483         HDEBUGLOGD(eDebugResourceManager, "%s", result.string());
484         for (uint32_t i = 0; i < display->mLayers.size(); i++) {
485             result.clear();
486             HDEBUGLOGD(eDebugResourceManager, "%d layer(%p) dump", i, display->mLayers[i]);
487             display->mLayers[i]->printLayer();
488             HDEBUGLOGD(eDebugResourceManager, "%s", result.string());
489         }
490     }
491 
492     if (mDevice->isLastValidate(display)) {
493         if ((ret = finishAssignResourceWork()) != NO_ERROR) {
494             HWC_LOGE(display, "%s:: finishAssignResourceWork() error (%d)",
495                     __func__, ret);
496             return ret;
497         }
498     }
499 
500     if (!display->mUseDpu) {
501         if (display->mClientCompositionInfo.mHasCompositionLayer) {
502             if ((ret = display->mExynosCompositionInfo.mM2mMPP->assignMPP(display, &display->mClientCompositionInfo)) != NO_ERROR)
503             {
504                 ALOGE("%s:: %s MPP assignMPP() error (%d)",
505                         __func__, display->mExynosCompositionInfo.mM2mMPP->mName.string(), ret);
506                 return ret;
507             }
508             int prevHasCompositionLayer = display->mExynosCompositionInfo.mHasCompositionLayer;
509             display->mExynosCompositionInfo.mHasCompositionLayer = true;
510             // if prevHasCompositionLayer is false, setResourcePriority is not called
511             if (prevHasCompositionLayer == false)
512                 setResourcePriority(display);
513         }
514     }
515 
516     return NO_ERROR;
517 }
518 
setResourcePriority(ExynosDisplay * display)519 int32_t ExynosResourceManager::setResourcePriority(ExynosDisplay *display)
520 {
521     int ret = NO_ERROR;
522     int check_ret = NO_ERROR;
523     ExynosMPP *m2mMPP = NULL;
524 
525     for (uint32_t i = 0; i < display->mLayers.size(); i++) {
526         ExynosLayer *layer = display->mLayers[i];
527         if ((layer->mValidateCompositionType == HWC2_COMPOSITION_DEVICE) &&
528             (layer->mM2mMPP != NULL) &&
529             (layer->mM2mMPP->mPhysicalType == MPP_G2D) &&
530             ((check_ret = layer->mM2mMPP->prioritize(2)) != NO_ERROR)) {
531             if (check_ret < 0) {
532                 HWC_LOGE(display, "Fail to set exynoscomposition priority(%d)", ret);
533             } else {
534                 m2mMPP = layer->mM2mMPP;
535                 layer->resetAssignedResource();
536                 layer->mOverlayInfo |= eResourcePendingWork;
537                 layer->mValidateCompositionType = HWC2_COMPOSITION_DEVICE;
538                 ret = EXYNOS_ERROR_CHANGED;
539                 HDEBUGLOGD(eDebugResourceManager, "\t%s is reserved without display because of panding work",
540                         m2mMPP->mName.string());
541                 m2mMPP->reserveMPP();
542                 layer->mCheckMPPFlag[m2mMPP->mLogicalType] = eMPPHWBusy;
543             }
544         }
545     }
546 
547     m2mMPP = display->mExynosCompositionInfo.mM2mMPP;
548     ExynosCompositionInfo &compositionInfo = display->mExynosCompositionInfo;
549     if (compositionInfo.mHasCompositionLayer == true)
550     {
551         if ((m2mMPP == NULL) || (m2mMPP->mAcrylicHandle == NULL)) {
552             HWC_LOGE(display, "There is exynos composition layers but resource is null (%p)",
553                     m2mMPP);
554         } else if ((check_ret = m2mMPP->prioritize(2)) != NO_ERROR) {
555             HDEBUGLOGD(eDebugResourceManager, "%s setting priority error(%d)", m2mMPP->mName.string(), check_ret);
556             if (check_ret < 0) {
557                 HWC_LOGE(display, "Fail to set exynoscomposition priority(%d)", ret);
558             } else {
559                 if (display->mExynosCompositionInfo.mFirstIndex >= 0) {
560                     uint32_t firstIndex = (uint32_t)display->mExynosCompositionInfo.mFirstIndex;
561                     uint32_t lastIndex = (uint32_t)display->mExynosCompositionInfo.mLastIndex;
562                     for (uint32_t i = firstIndex; i <= lastIndex; i++) {
563                         ExynosLayer *layer = display->mLayers[i];
564                         layer->resetAssignedResource();
565                         layer->mOverlayInfo |= eResourcePendingWork;
566                         layer->mValidateCompositionType = HWC2_COMPOSITION_DEVICE;
567                         layer->mCheckMPPFlag[m2mMPP->mLogicalType] = eMPPHWBusy;
568                     }
569                 }
570                 compositionInfo.initializeInfos(display);
571                 ret = EXYNOS_ERROR_CHANGED;
572                 m2mMPP->resetUsedCapacity();
573                 HDEBUGLOGD(eDebugResourceManager, "\t%s is reserved without display because of pending work",
574                         m2mMPP->mName.string());
575                 m2mMPP->reserveMPP();
576             }
577         } else {
578             HDEBUGLOGD(eDebugResourceManager, "%s setting priority is ok", m2mMPP->mName.string());
579         }
580     }
581 
582     return ret;
583 }
584 
assignResourceInternal(ExynosDisplay * display)585 int32_t ExynosResourceManager::assignResourceInternal(ExynosDisplay *display)
586 {
587     int ret = NO_ERROR;
588     int retry_count = 0;
589 
590     Mutex::Autolock lock(mDstBufMgrThread->mStateMutex);
591 
592     /*
593      * First add layers that SF requested HWC2_COMPOSITION_CLIENT type
594      * to client composition
595      */
596     for (uint32_t i = 0; i < display->mLayers.size(); i++) {
597         ExynosLayer *layer = display->mLayers[i];
598         if (layer->mCompositionType == HWC2_COMPOSITION_CLIENT) {
599             layer->mOverlayInfo |= eSkipLayer;
600             layer->mValidateCompositionType = HWC2_COMPOSITION_CLIENT;
601             if (((ret = display->addClientCompositionLayer(i)) != NO_ERROR) &&
602                  (ret != EXYNOS_ERROR_CHANGED)) {
603                 HWC_LOGE(display, "Handle HWC2_COMPOSITION_CLIENT type layers, but addClientCompositionLayer failed (%d)", ret);
604                 return ret;
605             }
606         }
607     }
608 
609     do {
610         HDEBUGLOGD(eDebugResourceManager, "%s:: retry_count(%d)", __func__, retry_count);
611         if ((ret = resetAssignedResources(display)) != NO_ERROR)
612             return ret;
613         if ((ret = assignCompositionTarget(display, COMPOSITION_CLIENT)) != NO_ERROR) {
614             HWC_LOGE(display, "%s:: Fail to assign resource for compositionTarget",
615                     __func__);
616             return ret;
617         }
618 
619         if ((ret = assignLayers(display, ePriorityMax)) != NO_ERROR) {
620             if (ret == EXYNOS_ERROR_CHANGED) {
621                 retry_count++;
622                 continue;
623             } else {
624                 HWC_LOGE(display, "%s:: Fail to assign resource for ePriorityMax layer",
625                         __func__);
626                 return ret;
627             }
628         }
629 
630         if ((ret = assignLayers(display, ePriorityHigh)) != NO_ERROR) {
631             if (ret == EXYNOS_ERROR_CHANGED) {
632                 retry_count++;
633                 continue;
634             } else {
635                 HWC_LOGE(display, "%s:: Fail to assign resource for ePriorityHigh layer",
636                         __func__);
637                 return ret;
638             }
639         }
640 
641         if ((ret = assignCompositionTarget(display, COMPOSITION_EXYNOS)) != NO_ERROR) {
642             if (ret == eInsufficientMPP) {
643                 /*
644                  * Change compositionTypes to HWC2_COMPOSITION_CLIENT
645                  */
646                 uint32_t firstIndex = (uint32_t)display->mExynosCompositionInfo.mFirstIndex;
647                 uint32_t lastIndex = (uint32_t)display->mExynosCompositionInfo.mLastIndex;
648                 for (uint32_t i = firstIndex; i <= lastIndex; i++) {
649                     ExynosLayer *layer = display->mLayers[i];
650                     layer->resetAssignedResource();
651                     layer->mOverlayInfo |= eInsufficientMPP;
652                     layer->mValidateCompositionType = HWC2_COMPOSITION_CLIENT;
653                     if (((ret = display->addClientCompositionLayer(i)) != NO_ERROR) &&
654                         (ret != EXYNOS_ERROR_CHANGED)) {
655                         HWC_LOGE(display, "Change compositionTypes to HWC2_COMPOSITION_CLIENT, but addClientCompositionLayer failed (%d)", ret);
656                         return ret;
657                     }
658                 }
659                 display->mExynosCompositionInfo.initializeInfos(display);
660                 ret = EXYNOS_ERROR_CHANGED;
661             } else {
662                 return ret;
663             }
664         }
665 
666         if (ret == NO_ERROR) {
667             for (int32_t i = ePriorityHigh - 1; i > ePriorityNone; i--) {
668                 if ((ret = assignLayers(display, i)) == EXYNOS_ERROR_CHANGED)
669                     break;
670                 if (ret != NO_ERROR)
671                     return ret;
672             }
673         }
674 
675         /* Assignment is done */
676         if (ret == NO_ERROR) {
677             ret = setResourcePriority(display);
678         }
679         retry_count++;
680     } while((ret == EXYNOS_ERROR_CHANGED) && (retry_count < ASSIGN_RESOURCE_TRY_COUNT));
681 
682     if (retry_count == ASSIGN_RESOURCE_TRY_COUNT) {
683         HWC_LOGE(display, "%s:: assign resources fail", __func__);
684         ret = eUnknown;
685         return ret;
686     } else {
687         if ((ret = updateExynosComposition(display)) != NO_ERROR)
688             return ret;
689         if ((ret = updateClientComposition(display)) != NO_ERROR)
690             return ret;
691     }
692 
693     if (hwcCheckDebugMessages(eDebugCapacity)) {
694         for (uint32_t i = 0; i < mM2mMPPs.size(); i++) {
695             if (mM2mMPPs[i]->mPhysicalType == MPP_G2D)
696             {
697                 String8 dumpMPP;
698                 mM2mMPPs[i]->dump(dumpMPP);
699                 HDEBUGLOGD(eDebugCapacity, "%s", dumpMPP.string());
700             }
701         }
702     }
703     return ret;
704 }
updateExynosComposition(ExynosDisplay * display)705 int32_t ExynosResourceManager::updateExynosComposition(ExynosDisplay *display)
706 {
707     int ret = NO_ERROR;
708     /* Use Exynos composition as many as possible */
709     if ((display->mExynosCompositionInfo.mHasCompositionLayer == true) &&
710         (display->mExynosCompositionInfo.mM2mMPP != NULL)) {
711         if (display->mDisplayControl.useMaxG2DSrc == 1) {
712             ExynosMPP *m2mMPP = display->mExynosCompositionInfo.mM2mMPP;
713             uint32_t lastIndex = display->mExynosCompositionInfo.mLastIndex;
714             uint32_t firstIndex = display->mExynosCompositionInfo.mFirstIndex;
715             uint32_t remainNum = m2mMPP->mMaxSrcLayerNum - (lastIndex - firstIndex + 1);
716 
717             HDEBUGLOGD(eDebugResourceManager, "Update ExynosComposition firstIndex: %d, lastIndex: %d, remainNum: %d++++",
718                     firstIndex, lastIndex, remainNum);
719 
720             ExynosLayer *layer = NULL;
721             exynos_image src_img;
722             exynos_image dst_img;
723             if (remainNum > 0) {
724                 for (uint32_t i = (lastIndex + 1); i < display->mLayers.size(); i++)
725                 {
726                     layer = display->mLayers[i];
727                     layer->setSrcExynosImage(&src_img);
728                     layer->setDstExynosImage(&dst_img);
729                     layer->setExynosImage(src_img, dst_img);
730                     bool isAssignable = false;
731                     if ((layer->mSupportedMPPFlag & m2mMPP->mLogicalType) != 0)
732                         isAssignable = m2mMPP->isAssignable(display, src_img, dst_img);
733 
734                     bool canChange = (layer->mValidateCompositionType != HWC2_COMPOSITION_CLIENT) &&
735                                      ((display->mDisplayControl.cursorSupport == false) ||
736                                       (layer->mCompositionType != HWC2_COMPOSITION_CURSOR)) &&
737                                      (layer->mSupportedMPPFlag & m2mMPP->mLogicalType) && isAssignable;
738 
739                     HDEBUGLOGD(eDebugResourceManager, "\tlayer[%d] type: %d, 0x%8x, isAssignable: %d, canChange: %d, remainNum(%d)",
740                             i, layer->mValidateCompositionType,
741                             layer->mSupportedMPPFlag, isAssignable, canChange, remainNum);
742                     if (canChange) {
743                         layer->resetAssignedResource();
744                         layer->mOverlayInfo |= eUpdateExynosComposition;
745                         if ((ret = m2mMPP->assignMPP(display, layer)) != NO_ERROR)
746                         {
747                             ALOGE("%s:: %s MPP assignMPP() error (%d)",
748                                     __func__, m2mMPP->mName.string(), ret);
749                             return ret;
750                         }
751                         layer->setExynosMidImage(dst_img);
752                         display->addExynosCompositionLayer(i);
753                         layer->mValidateCompositionType = HWC2_COMPOSITION_EXYNOS;
754                         remainNum--;
755                     }
756                     if ((canChange == false) || (remainNum == 0))
757                         break;
758                 }
759             }
760             if (remainNum > 0) {
761                 for (int32_t i = (firstIndex - 1); i >= 0; i--)
762                 {
763                     layer = display->mLayers[i];
764                     layer->setSrcExynosImage(&src_img);
765                     layer->setDstExynosImage(&dst_img);
766                     layer->setExynosImage(src_img, dst_img);
767                     bool isAssignable = false;
768                     if ((layer->mSupportedMPPFlag & m2mMPP->mLogicalType) != 0)
769                         isAssignable = m2mMPP->isAssignable(display, src_img, dst_img);
770 
771                     bool canChange = (layer->mValidateCompositionType != HWC2_COMPOSITION_CLIENT) &&
772                                      ((display->mDisplayControl.cursorSupport == false) ||
773                                       (layer->mCompositionType != HWC2_COMPOSITION_CURSOR)) &&
774                                      (layer->mSupportedMPPFlag & m2mMPP->mLogicalType) && isAssignable;
775 
776                     HDEBUGLOGD(eDebugResourceManager, "\tlayer[%d] type: %d, 0x%8x, isAssignable: %d, canChange: %d, remainNum(%d)",
777                             i, layer->mValidateCompositionType,
778                             layer->mSupportedMPPFlag, isAssignable, canChange, remainNum);
779                     if (canChange) {
780                         layer->resetAssignedResource();
781                         layer->mOverlayInfo |= eUpdateExynosComposition;
782                         if ((ret = m2mMPP->assignMPP(display, layer)) != NO_ERROR)
783                         {
784                             ALOGE("%s:: %s MPP assignMPP() error (%d)",
785                                     __func__, m2mMPP->mName.string(), ret);
786                             return ret;
787                         }
788                         layer->setExynosMidImage(dst_img);
789                         display->addExynosCompositionLayer(i);
790                         layer->mValidateCompositionType = HWC2_COMPOSITION_EXYNOS;
791                         remainNum--;
792                     }
793                     if ((canChange == false) || (remainNum == 0))
794                         break;
795                 }
796             }
797             HDEBUGLOGD(eDebugResourceManager, "Update ExynosComposition firstIndex: %d, lastIndex: %d, remainNum: %d-----",
798                     display->mExynosCompositionInfo.mFirstIndex, display->mExynosCompositionInfo.mLastIndex, remainNum);
799         }
800 
801         /*
802          * Check if there is only one exynos composition layer
803          * Then it is not composition and m2mMPP is not required
804          * if internalMPP can process the layer alone.
805          */
806         ExynosMPP *otfMPP = display->mExynosCompositionInfo.mOtfMPP;
807         if ((display->mDisplayControl.enableExynosCompositionOptimization == true) &&
808             (otfMPP != NULL) &&
809             (display->mExynosCompositionInfo.mFirstIndex >= 0) &&
810             (display->mExynosCompositionInfo.mFirstIndex == display->mExynosCompositionInfo.mLastIndex))
811         {
812             ExynosLayer* layer = display->mLayers[display->mExynosCompositionInfo.mFirstIndex];
813             if (layer->mSupportedMPPFlag & otfMPP->mLogicalType) {
814                 layer->resetAssignedResource();
815                 layer->mValidateCompositionType = HWC2_COMPOSITION_DEVICE;
816                 display->mExynosCompositionInfo.initializeInfos(display);
817                 // reset otfMPP
818                 if ((ret = otfMPP->resetAssignedState()) != NO_ERROR)
819                 {
820                     ALOGE("%s:: %s MPP resetAssignedState() error (%d)",
821                             __func__, otfMPP->mName.string(), ret);
822                 }
823                 // assign otfMPP again
824                 if ((ret = otfMPP->assignMPP(display, layer)) != NO_ERROR)
825                 {
826                     ALOGE("%s:: %s MPP assignMPP() error (%d)",
827                             __func__, otfMPP->mName.string(), ret);
828                 }
829             }
830         }
831     }
832     return ret;
833 }
834 
changeLayerFromClientToDevice(ExynosDisplay * display,ExynosLayer * layer,uint32_t layer_index,exynos_image m2m_out_img,ExynosMPP * m2mMPP,ExynosMPP * otfMPP)835 int32_t ExynosResourceManager::changeLayerFromClientToDevice(ExynosDisplay *display, ExynosLayer *layer,
836         uint32_t layer_index, exynos_image m2m_out_img, ExynosMPP *m2mMPP, ExynosMPP *otfMPP)
837 {
838     int ret = NO_ERROR;
839     if ((ret = display->removeClientCompositionLayer(layer_index)) != NO_ERROR) {
840         ALOGD("removeClientCompositionLayer return error(%d)", ret);
841         return ret;
842     }
843     if (otfMPP != NULL) {
844         if ((ret = otfMPP->assignMPP(display, layer)) != NO_ERROR)
845         {
846             ALOGE("%s:: %s MPP assignMPP() error (%d)",
847                     __func__, otfMPP->mName.string(), ret);
848             return ret;
849         }
850         HDEBUGLOGD(eDebugResourceManager, "\t\t[%d] layer: %s MPP is assigned",
851                 layer_index, otfMPP->mName.string());
852     }
853     if (m2mMPP != NULL) {
854         if ((ret = m2mMPP->assignMPP(display, layer)) != NO_ERROR)
855         {
856             ALOGE("%s:: %s MPP assignMPP() error (%d)",
857                     __func__, m2mMPP->mName.string(), ret);
858             return ret;
859         }
860         layer->setExynosMidImage(m2m_out_img);
861         HDEBUGLOGD(eDebugResourceManager, "\t\t[%d] layer: %s MPP is assigned",
862                 layer_index, m2mMPP->mName.string());
863     }
864     layer->mValidateCompositionType = HWC2_COMPOSITION_DEVICE;
865     display->mWindowNumUsed++;
866     HDEBUGLOGD(eDebugResourceManager, "\t\t[%d] layer: mWindowNumUsed(%d)",
867             layer_index, display->mWindowNumUsed);
868 
869     return ret;
870 }
updateClientComposition(ExynosDisplay * display)871 int32_t ExynosResourceManager::updateClientComposition(ExynosDisplay *display)
872 {
873     int ret = NO_ERROR;
874 
875     if (display->mDisplayControl.enableClientCompositionOptimization == false)
876         return ret;
877 
878     if ((exynosHWCControl.forceGpu == 1) ||
879         (display->mClientCompositionInfo.mHasCompositionLayer == false))
880         return ret;
881 
882     /* Check if there is layer that can be handled by overlay */
883     int32_t firstIndex = display->mClientCompositionInfo.mFirstIndex;
884     int32_t lastIndex = display->mClientCompositionInfo.mLastIndex;
885 
886     /* Don't optimize if only low fps layers are composited by GLES */
887     if ((display->mLowFpsLayerInfo.mHasLowFpsLayer == true) &&
888         (display->mLowFpsLayerInfo.mFirstIndex == firstIndex) &&
889         (display->mLowFpsLayerInfo.mLastIndex == lastIndex))
890         return ret;
891 
892     for (int32_t i = firstIndex; i <= lastIndex; i++) {
893         ExynosMPP *m2mMPP = NULL;
894         ExynosMPP *otfMPP = NULL;
895         exynos_image m2m_out_img;
896         uint32_t overlayInfo = 0;
897         int32_t compositionType = 0;
898         ExynosLayer *layer = display->mLayers[i];
899         if ((layer->mOverlayPriority >= ePriorityHigh) &&
900             (layer->mValidateCompositionType == HWC2_COMPOSITION_DEVICE)) {
901             display->mClientCompositionInfo.mFirstIndex++;
902             continue;
903         }
904         compositionType = assignLayer(display, layer, i, m2m_out_img, &m2mMPP, &otfMPP, overlayInfo);
905         if (compositionType == HWC2_COMPOSITION_DEVICE) {
906             /*
907              * Don't allocate G2D
908              * Execute can be fail because of other job
909              * Prioritizing is required to allocate G2D
910              */
911             if ((m2mMPP != NULL) && (m2mMPP->mPhysicalType == MPP_G2D))
912                 break;
913 
914             if ((ret = changeLayerFromClientToDevice(display, layer, i, m2m_out_img, m2mMPP, otfMPP)) != NO_ERROR)
915                 return ret;
916         } else {
917             break;
918         }
919     }
920 
921     firstIndex = display->mClientCompositionInfo.mFirstIndex;
922     lastIndex = display->mClientCompositionInfo.mLastIndex;
923     for (int32_t i = lastIndex; i >= 0; i--) {
924         ExynosMPP *m2mMPP = NULL;
925         ExynosMPP *otfMPP = NULL;
926         exynos_image m2m_out_img;
927         uint32_t overlayInfo = 0;
928         int32_t compositionType = 0;
929         ExynosLayer *layer = display->mLayers[i];
930         if ((layer->mOverlayPriority >= ePriorityHigh) &&
931             (layer->mValidateCompositionType == HWC2_COMPOSITION_DEVICE)) {
932             display->mClientCompositionInfo.mLastIndex--;
933             continue;
934         }
935         compositionType = assignLayer(display, layer, i, m2m_out_img, &m2mMPP, &otfMPP, overlayInfo);
936         if (compositionType == HWC2_COMPOSITION_DEVICE) {
937             /*
938              * Don't allocate G2D
939              * Execute can be fail because of other job
940              * Prioritizing is required to allocate G2D
941              */
942             if ((m2mMPP != NULL) && (m2mMPP->mPhysicalType == MPP_G2D))
943                 break;
944             if ((ret = changeLayerFromClientToDevice(display, layer, i, m2m_out_img, m2mMPP, otfMPP)) != NO_ERROR)
945                 return ret;
946         } else {
947             break;
948         }
949     }
950 
951     return ret;
952 }
953 
resetAssignedResources(ExynosDisplay * display,bool forceReset)954 int32_t ExynosResourceManager::resetAssignedResources(ExynosDisplay * display, bool forceReset)
955 {
956     for (uint32_t i = 0; i < mOtfMPPs.size(); i++) {
957         if (mOtfMPPs[i]->mAssignedDisplay != display)
958             continue;
959 
960         mOtfMPPs[i]->resetAssignedState();
961     }
962     for (uint32_t i = 0; i < mM2mMPPs.size(); i++) {
963         if (mM2mMPPs[i]->mAssignedDisplay != display)
964             continue;
965         if ((forceReset == false) &&
966             ((mM2mMPPs[i]->mLogicalType == MPP_LOGICAL_G2D_RGB) ||
967              (mM2mMPPs[i]->mLogicalType == MPP_LOGICAL_G2D_COMBO)))
968         {
969             /*
970              * Don't reset assigned state
971              */
972             continue;
973         }
974         mM2mMPPs[i]->resetAssignedState();
975     }
976     display->mWindowNumUsed = 0;
977 
978     return NO_ERROR;
979 }
980 
assignCompositionTarget(ExynosDisplay * display,uint32_t targetType)981 int32_t ExynosResourceManager::assignCompositionTarget(ExynosDisplay * display, uint32_t targetType)
982 {
983     int32_t ret = NO_ERROR;
984     ExynosCompositionInfo *compositionInfo;
985 
986     HDEBUGLOGD(eDebugResourceManager, "%s:: display(%d), targetType(%d) +++++",
987             __func__, display->mType, targetType);
988 
989     if (targetType == COMPOSITION_CLIENT)
990         compositionInfo = &(display->mClientCompositionInfo);
991     else if (targetType == COMPOSITION_EXYNOS)
992         compositionInfo = &(display->mExynosCompositionInfo);
993     else
994         return -EINVAL;
995 
996     if (compositionInfo->mHasCompositionLayer == false)
997     {
998         HDEBUGLOGD(eDebugResourceManager, "\tthere is no composition layers");
999         return NO_ERROR;
1000     }
1001 
1002     exynos_image src_img;
1003     exynos_image dst_img;
1004     display->setCompositionTargetExynosImage(targetType, &src_img, &dst_img);
1005 
1006     if (targetType == COMPOSITION_EXYNOS) {
1007         for (uint32_t i = 0; i < mM2mMPPs.size(); i++) {
1008             if ((display->mUseDpu == true) &&
1009                 (mM2mMPPs[i]->mLogicalType != MPP_LOGICAL_G2D_RGB))
1010                 continue;
1011             if ((display->mUseDpu == false) &&
1012                 (mM2mMPPs[i]->mLogicalType != MPP_LOGICAL_G2D_COMBO))
1013                 continue;
1014             if (mM2mMPPs[i]->isAssignableState(display, src_img, dst_img)) {
1015                 /* assignMPP(display, compositionInfo) is not called hear
1016                  * assignMPP() was called already during assigning layer
1017                  * Source of M2mMPP should be Layer, not composition target buffer*/
1018                 compositionInfo->mM2mMPP = mM2mMPPs[i];
1019             }
1020         }
1021         if (compositionInfo->mM2mMPP == NULL) {
1022             HWC_LOGE(display, "%s:: fail to assign M2mMPP (%d)",__func__, ret);
1023             return eInsufficientMPP;
1024         }
1025     }
1026 
1027     if ((compositionInfo->mFirstIndex < 0) ||
1028         (compositionInfo->mLastIndex < 0)) {
1029         HWC_LOGE(display, "%s:: layer index is not valid mFirstIndex(%d), mLastIndex(%d)",
1030                 __func__, compositionInfo->mFirstIndex, compositionInfo->mLastIndex);
1031         return -EINVAL;
1032     }
1033 
1034     if (display->mUseDpu == false) {
1035         return NO_ERROR;
1036     }
1037 
1038     int64_t isSupported = 0;
1039     bool isAssignable = false;
1040     for (uint32_t i = 0; i < mOtfMPPs.size(); i++) {
1041         isSupported = mOtfMPPs[i]->isSupported(*display, src_img, dst_img);
1042         if (isSupported == NO_ERROR)
1043             isAssignable = mOtfMPPs[i]->isAssignable(display, src_img, dst_img);
1044 
1045         HDEBUGLOGD(eDebugResourceManager, "\t\t check %s: supportedBit(0x%" PRIx64 "), isAssignable(%d)",
1046                 mOtfMPPs[i]->mName.string(), -isSupported, isAssignable);
1047         if ((isSupported == NO_ERROR) && (isAssignable)) {
1048             if ((ret = mOtfMPPs[i]->assignMPP(display, compositionInfo)) != NO_ERROR)
1049             {
1050                 HWC_LOGE(display, "%s:: %s MPP assignMPP() error (%d)",
1051                         __func__, mOtfMPPs[i]->mName.string(), ret);
1052                 return ret;
1053             }
1054             compositionInfo->setExynosImage(src_img, dst_img);
1055             compositionInfo->setExynosMidImage(dst_img);
1056             compositionInfo->mOtfMPP = mOtfMPPs[i];
1057             display->mWindowNumUsed++;
1058 
1059             HDEBUGLOGD(eDebugResourceManager, "%s:: %s is assigned", __func__, mOtfMPPs[i]->mName.string());
1060             return NO_ERROR;
1061         }
1062     }
1063 
1064     HDEBUGLOGD(eDebugResourceManager, "%s:: insufficient MPP", __func__);
1065     return eInsufficientMPP;
1066 }
1067 
validateLayer(uint32_t index,ExynosDisplay * display,ExynosLayer * layer)1068 int32_t ExynosResourceManager::validateLayer(uint32_t index, ExynosDisplay *display, ExynosLayer *layer)
1069 {
1070     if ((layer == NULL) || (display == NULL))
1071         return eUnknown;
1072 
1073     if (exynosHWCControl.forceGpu == 1) {
1074         if ((layer->mLayerBuffer == NULL) ||
1075             (getDrmMode(layer->mLayerBuffer) == NO_DRM))
1076             return eForceFbEnabled;
1077     }
1078 
1079     if ((display->mLayers.size() >= MAX_OVERLAY_LAYER_NUM) &&
1080         (layer->mOverlayPriority < ePriorityHigh))
1081         return eExceedMaxLayerNum;
1082 
1083     if ((layer->mLayerBuffer != NULL) &&
1084         (getDrmMode(layer->mLayerBuffer) == NO_DRM) &&
1085         (display->mDREnable == true) &&
1086         (display->mDynamicReCompMode == DEVICE_2_CLIENT))
1087         return eDynamicRecomposition;
1088 
1089     if ((layer->mLayerBuffer != NULL) &&
1090             (display->mDisplayId == getDisplayId(HWC_DISPLAY_PRIMARY, 0)) &&
1091             (mForceReallocState != DST_REALLOC_DONE)) {
1092         ALOGI("Device type assign skipping by dst reallocation...... ");
1093         return eReallocOnGoingForDDI;
1094     }
1095 
1096     if (layer->mCompositionType == HWC2_COMPOSITION_CLIENT)
1097         return eSkipLayer;
1098 
1099 #ifndef HWC_SUPPORT_COLOR_TRANSFORM
1100     if (display->mColorTransformHint != HAL_COLOR_TRANSFORM_IDENTITY) {
1101         HWC_LOGE(display, "unsupported color transform");
1102         return eUnSupportedColorTransform;
1103     }
1104 #else
1105     if ((display->mColorTransformHint < 0) &&
1106         (layer->mOverlayPriority < ePriorityHigh))
1107         return eUnSupportedColorTransform;
1108 #endif
1109 
1110     if ((display->mLowFpsLayerInfo.mHasLowFpsLayer == true) &&
1111         (display->mLowFpsLayerInfo.mFirstIndex <= (int32_t)index) &&
1112         ((int32_t)index <= display->mLowFpsLayerInfo.mLastIndex))
1113         return eLowFpsLayer;
1114 
1115     if(layer->isDimLayer() && layer->mLayerBuffer == NULL) {
1116         return eDimLayer;
1117     }
1118 
1119     if (!(display->mType == HWC_DISPLAY_VIRTUAL &&
1120         ((ExynosVirtualDisplay *)display)->mIsWFDState == (int)LLWFD))
1121 
1122     if (layer->mLayerBuffer == NULL)
1123         return eInvalidHandle;
1124     if (isSrcCropFloat(layer->mPreprocessedInfo.sourceCrop))
1125         return eHasFloatSrcCrop;
1126 
1127     if ((layer->mPreprocessedInfo.displayFrame.left < 0) ||
1128         (layer->mPreprocessedInfo.displayFrame.top < 0) ||
1129         (layer->mPreprocessedInfo.displayFrame.right > (int32_t)display->mXres) ||
1130         (layer->mPreprocessedInfo.displayFrame.bottom > (int32_t)display->mYres))
1131         return eInvalidDispFrame;
1132 
1133     return NO_ERROR;
1134 }
1135 
getAlignedImage(exynos_image image,const ExynosMPP * m2mMpp,const ExynosMPP * otfMpp) const1136 exynos_image ExynosResourceManager::getAlignedImage(exynos_image image, const ExynosMPP *m2mMpp,
1137                                                     const ExynosMPP *otfMpp) const {
1138     const auto srcCropWidthAlign = otfMpp ? otfMpp->getSrcCropWidthAlign(image) : 1;
1139     const auto srcCropHeightAlign = otfMpp ? otfMpp->getSrcCropHeightAlign(image) : 1;
1140     const auto dstwidthAlign = m2mMpp ? m2mMpp->getDstWidthAlign(image) : 1;
1141     const auto dstHeightAlign = m2mMpp ? m2mMpp->getDstHeightAlign(image) : 1;
1142 
1143     const auto widthAlign = std::lcm(srcCropWidthAlign, dstwidthAlign);
1144     const auto heighAlign = std::lcm(srcCropHeightAlign, dstHeightAlign);
1145 
1146     image.w = pixel_align(image.w, widthAlign);
1147     image.h = pixel_align(image.h, heighAlign);
1148 
1149     return image;
1150 }
1151 
getCandidateScalingM2mMPPOutImages(const ExynosDisplay * display,const exynos_image & src_img,const exynos_image & dst_img,std::vector<exynos_image> & image_lists)1152 void ExynosResourceManager::getCandidateScalingM2mMPPOutImages(
1153         const ExynosDisplay *display, const exynos_image &src_img, const exynos_image &dst_img,
1154         std::vector<exynos_image> &image_lists) {
1155     const bool isPerpendicular = !!(src_img.transform & HAL_TRANSFORM_ROT_90);
1156     const uint32_t srcWidth = isPerpendicular ? src_img.h : src_img.w;
1157     const uint32_t srcHeight = isPerpendicular ? src_img.w : src_img.h;
1158 
1159     const bool scaleUp = (srcWidth < dst_img.w && srcHeight < dst_img.h);
1160     const bool scaleDown = (srcWidth > dst_img.w && srcHeight > dst_img.h);
1161 
1162     if (!scaleUp && !scaleDown) {
1163         return;
1164     }
1165 
1166     /* otfMPP doesn't rotate image, m2mMPP rotates image */
1167     exynos_image dst_scale_img = dst_img;
1168 
1169     if (hasHdrInfo(src_img)) {
1170         if (isFormatYUV(src_img.format))
1171             dst_scale_img.format = HAL_PIXEL_FORMAT_YCBCR_P010;
1172         else
1173             dst_scale_img.format = HAL_PIXEL_FORMAT_RGBA_1010102;
1174     } else {
1175         if (isFormatYUV(src_img.format)) {
1176             dst_scale_img.format = DEFAULT_MPP_DST_YUV_FORMAT;
1177         }
1178     }
1179 
1180     ExynosMPP *otfMpp = nullptr;
1181     ExynosMPP *m2mMpp = nullptr;
1182     uint32_t otfMppRatio = 1;
1183     uint32_t m2mMppRatio = 1;
1184     if (scaleUp) {
1185         std::find_if(mOtfMPPs.begin(), mOtfMPPs.end(),
1186                      [&dst_scale_img, &dst_img, &otfMpp, &otfMppRatio](auto m) {
1187                          auto ratio = m->getMaxUpscale(dst_scale_img, dst_img);
1188                          if (ratio > 1) {
1189                              otfMpp = m;
1190                              otfMppRatio = ratio;
1191                              return true;
1192                          }
1193                          return false;
1194                      });
1195         const auto reqRatio = max(float(dst_img.w) / float(srcWidth * otfMppRatio),
1196                                   float(dst_img.h) / float(srcHeight * otfMppRatio));
1197         std::find_if(mM2mMPPs.begin(), mM2mMPPs.end(),
1198                      [&src_img, &dst_scale_img, reqRatio, &m2mMpp, &m2mMppRatio](auto m) {
1199                          float ratio = float(m->getMaxUpscale(src_img, dst_scale_img));
1200                          if (ratio > reqRatio) {
1201                              m2mMpp = m;
1202                              m2mMppRatio = ratio;
1203                              return true;
1204                          }
1205                          return false;
1206                      });
1207     } else {
1208         std::find_if(mM2mMPPs.begin(), mM2mMPPs.end(),
1209                      [&src_img, &dst_scale_img, display, &m2mMpp, &m2mMppRatio](auto m) {
1210                          auto ratio = m->getMaxDownscale(*display, src_img, dst_scale_img);
1211                          if (ratio > 1) {
1212                              m2mMpp = m;
1213                              m2mMppRatio = ratio;
1214                              return true;
1215                          }
1216                          return false;
1217                      });
1218 
1219         const float otfSrcWidth = float(srcWidth / m2mMppRatio);
1220         const float scaleRatio_H = otfSrcWidth / float(dst_img.w);
1221         const float otfSrcHeight = float(srcWidth / m2mMppRatio);
1222         const float scaleRatio_V = otfSrcHeight / float(dst_img.h);
1223         const float displayRatio_V = float(dst_img.h) / float(display->mYres);
1224         const float resolution = otfSrcWidth * otfSrcHeight * display->getBtsRefreshRate() / 1000;
1225 
1226         std::find_if(mOtfMPPs.begin(), mOtfMPPs.end(),
1227                      [&dst_scale_img, &dst_img, resolution, scaleRatio_H, scaleRatio_V,
1228                       displayRatio_V, &otfMpp, &otfMppRatio](auto m) {
1229                          auto ratio = m->getDownscaleRestriction(dst_scale_img, dst_img);
1230 
1231                          if (ratio >= scaleRatio_H && ratio >= scaleRatio_V &&
1232                              m->checkDownscaleCap(resolution, displayRatio_V)) {
1233                              otfMpp = m;
1234                              otfMppRatio = ratio;
1235                              return true;
1236                          }
1237                          return false;
1238                      });
1239     }
1240 
1241     if (!otfMpp && !m2mMpp) {
1242         HDEBUGLOGD(eDebugResourceManager,
1243                    "Cannot find available MPP for scaling src %d x %d, dst %d x %d", src_img.w,
1244                    src_img.h, dst_img.w, dst_img.h);
1245         return;
1246     }
1247 
1248     dst_scale_img.x = 0;
1249     dst_scale_img.y = 0;
1250     dst_scale_img.w = scaleDown ? dst_img.w : srcWidth;
1251     dst_scale_img.h = scaleDown ? dst_img.h : srcHeight;
1252 
1253     HDEBUGLOGD(eDebugResourceManager,
1254                "scaling w: %d, h: %d, ratio = otfType %d - %d, m2mType %d - %d", dst_scale_img.w,
1255                dst_scale_img.h, otfMpp ? otfMpp->mLogicalType : -1, otfMppRatio,
1256                m2mMpp ? m2mMpp->mLogicalType : -1, m2mMppRatio);
1257     if (scaleUp) {
1258         if (dst_scale_img.w * otfMppRatio < dst_img.w) {
1259             dst_scale_img.w = uint32_t(ceilf(float(dst_img.w) / float(otfMppRatio)));
1260         }
1261         if (dst_scale_img.h * otfMppRatio < dst_img.h) {
1262             dst_scale_img.h = uint32_t(ceilf(float(dst_img.h) / float(otfMppRatio)));
1263         }
1264     } else {
1265         if (dst_scale_img.w * m2mMppRatio < srcWidth) {
1266             dst_scale_img.w = uint32_t(ceilf(float(srcWidth) / float(m2mMppRatio)));
1267         }
1268         if (dst_scale_img.h * m2mMppRatio < srcHeight) {
1269             dst_scale_img.h = uint32_t(ceilf(float(srcHeight) / float(m2mMppRatio)));
1270         }
1271     }
1272     HDEBUGLOGD(eDebugResourceManager,
1273                "\tsrc[%d, %d, %d,%d], dst[%d, %d, %d,%d], mid[%d, %d, %d, %d]", src_img.x,
1274                src_img.y, src_img.w, src_img.h, dst_img.x, dst_img.y, dst_img.w, dst_img.h,
1275                dst_scale_img.x, dst_scale_img.y, dst_scale_img.w, dst_scale_img.h);
1276 
1277     if (isFormatSBWC(dst_scale_img.format)) {
1278         image_lists.emplace_back(getAlignedImage(dst_scale_img, m2mMpp, otfMpp));
1279         /*
1280          * SBWC format could not be supported in specific dst size
1281          * Add uncompressed YUV format to cover this size
1282          */
1283         dst_scale_img.format = DEFAULT_MPP_DST_UNCOMP_YUV_FORMAT;
1284     }
1285 
1286     image_lists.emplace_back(getAlignedImage(dst_scale_img, m2mMpp, otfMpp));
1287 }
1288 
getCandidateM2mMPPOutImages(ExynosDisplay * display,ExynosLayer * layer,std::vector<exynos_image> & image_lists)1289 int32_t ExynosResourceManager::getCandidateM2mMPPOutImages(ExynosDisplay *display,
1290         ExynosLayer *layer, std::vector<exynos_image> &image_lists)
1291 {
1292     exynos_image src_img;
1293     exynos_image dst_img;
1294     layer->setSrcExynosImage(&src_img);
1295     layer->setDstExynosImage(&dst_img);
1296     /* Position is (0, 0) */
1297     dst_img.x = 0;
1298     dst_img.y = 0;
1299 
1300     /* Check original source format first */
1301     dst_img.format = src_img.format;
1302     dst_img.dataSpace = src_img.dataSpace;
1303 
1304     /* Copy origin source HDR metadata */
1305     dst_img.metaParcel = src_img.metaParcel;
1306 
1307     getCandidateScalingM2mMPPOutImages(display, src_img, dst_img, image_lists);
1308 
1309     if (isFormatYUV(src_img.format) && !hasHdrInfo(src_img)) {
1310         dst_img.format = DEFAULT_MPP_DST_YUV_FORMAT;
1311     }
1312 
1313     ExynosExternalDisplay *external_display =
1314         (ExynosExternalDisplay*)mDevice->getDisplay(getDisplayId(HWC_DISPLAY_EXTERNAL, 0));
1315 
1316     /* For HDR through MSC or G2D case but dataspace is not changed */
1317     if (hasHdrInfo(src_img)) {
1318         if (isFormatYUV(src_img.format))
1319             dst_img.format = HAL_PIXEL_FORMAT_YCBCR_P010;
1320         else
1321             dst_img.format = HAL_PIXEL_FORMAT_RGBA_1010102;
1322         dst_img.dataSpace = src_img.dataSpace;
1323 
1324         /*
1325          * Align dst size
1326          * HDR10Plus should able to be processed by VGRFS
1327          * HDR on primary display should be processed by VGRFS
1328          * when external display is connected
1329          * because G2D is used by external display
1330          */
1331         if (hasHdr10Plus(dst_img) ||
1332             ((external_display != NULL) && (external_display->mPlugState) &&
1333              (display->mType == HWC_DISPLAY_PRIMARY))) {
1334             ExynosMPP *otfMppForHDRPlus = nullptr;
1335             auto mpp_it = std::find_if(mOtfMPPs.begin(), mOtfMPPs.end(),
1336                     [](auto m) {
1337                     return (m->mAttr & MPP_ATTR_HDR10PLUS);
1338                     });
1339             otfMppForHDRPlus = mpp_it == mOtfMPPs.end() ? nullptr : *mpp_it;
1340             uint32_t srcCropWidthAlign = 1;
1341             uint32_t srcCropHeightAlign = 1;
1342             if (otfMppForHDRPlus) {
1343                 srcCropWidthAlign = otfMppForHDRPlus->getSrcCropWidthAlign(dst_img);
1344                 srcCropHeightAlign = otfMppForHDRPlus->getSrcCropHeightAlign(dst_img);
1345             }
1346             dst_img.w = pixel_align(dst_img.w, srcCropWidthAlign);
1347             dst_img.h = pixel_align(dst_img.h, srcCropHeightAlign);
1348         }
1349     }
1350 
1351     image_lists.push_back(dst_img);
1352     if (isFormatSBWC(dst_img.format)) {
1353         /*
1354          * SBWC format could not be supported in specific dst size
1355          * Add uncompressed YUV format to cover this size
1356          */
1357         dst_img.format = DEFAULT_MPP_DST_UNCOMP_YUV_FORMAT;
1358         image_lists.push_back(dst_img);
1359     }
1360 
1361     /* For G2D HDR case */
1362     if (hasHdrInfo(src_img)) {
1363         bool isExternalPlugged = false;
1364         isHdrExternal = false;
1365 
1366         if (external_display != NULL) {
1367             if (external_display->mPlugState) isExternalPlugged = true;
1368             if (isExternalPlugged && (external_display->mExternalHdrSupported == true))
1369                 isHdrExternal = true;
1370         }
1371 
1372         if (isHdrExternal && (display->mType == HWC_DISPLAY_EXTERNAL)) {
1373             dst_img.format = HAL_PIXEL_FORMAT_RGBA_1010102;
1374             dst_img.dataSpace = src_img.dataSpace;
1375         } else {
1376             uint32_t dataspace = HAL_DATASPACE_UNKNOWN;
1377             if (display->mColorMode == HAL_COLOR_MODE_NATIVE) {
1378                 dataspace = HAL_DATASPACE_DCI_P3;
1379                 dataspace &= ~HAL_DATASPACE_TRANSFER_MASK;
1380                 dataspace |= HAL_DATASPACE_TRANSFER_GAMMA2_2;
1381                 dataspace &= ~HAL_DATASPACE_RANGE_MASK;
1382                 dataspace |= HAL_DATASPACE_RANGE_LIMITED;
1383             } else {
1384                 dataspace = colorModeToDataspace(display->mColorMode);
1385             }
1386             dst_img.format = HAL_PIXEL_FORMAT_RGBX_8888;
1387             dst_img.dataSpace = (android_dataspace)dataspace;
1388         }
1389 
1390         /*
1391          * This image is not pushed for primary display
1392          * if external display is connected
1393          * because G2D is used only for HDR on exernal display
1394          */
1395         if (!(isExternalPlugged && (display->mType == HWC_DISPLAY_PRIMARY))) {
1396             image_lists.push_back(dst_img);
1397         }
1398     }
1399 
1400     if (isFormatYUV(src_img.format) && !hasHdrInfo(src_img)) {
1401         /* Check RGB format */
1402         dst_img.format = DEFAULT_MPP_DST_FORMAT;
1403         if (display->mColorMode == HAL_COLOR_MODE_NATIVE) {
1404             /* Bypass dataSpace */
1405             dst_img.dataSpace = src_img.dataSpace;
1406         } else {
1407             /* Covert data space */
1408             dst_img.dataSpace = colorModeToDataspace(display->mColorMode);
1409         }
1410         image_lists.push_back(dst_img);
1411     }
1412 
1413     /*
1414      * image_lists[] would be src of otfMPP.
1415      * Layer color transform should be addressed
1416      * with dataspace conversion.
1417      * It should be addressed by m2mMPP if m2mMPP converts dataspace.
1418      * In other cases, m2mMPP ignores color transform setting and
1419      * otfMPP addresses layer color transform if it is necessary.
1420      */
1421     for (auto &image: image_lists) {
1422         if (image.dataSpace == src_img.dataSpace)
1423             image.needColorTransform = src_img.needColorTransform;
1424         else
1425             image.needColorTransform = false;
1426 
1427     }
1428 
1429     return static_cast<int32_t>(image_lists.size());
1430 }
1431 
assignLayer(ExynosDisplay * display,ExynosLayer * layer,uint32_t layer_index,exynos_image & m2m_out_img,ExynosMPP ** m2mMPP,ExynosMPP ** otfMPP,uint32_t & overlayInfo)1432 int32_t ExynosResourceManager::assignLayer(ExynosDisplay *display, ExynosLayer *layer, uint32_t layer_index,
1433         exynos_image &m2m_out_img, ExynosMPP **m2mMPP, ExynosMPP **otfMPP, uint32_t &overlayInfo)
1434 {
1435     int32_t ret = NO_ERROR;
1436     uint32_t validateFlag = 0;
1437 
1438     exynos_image src_img;
1439     exynos_image dst_img;
1440     layer->setSrcExynosImage(&src_img);
1441     layer->setDstExynosImage(&dst_img);
1442     layer->setExynosImage(src_img, dst_img);
1443     layer->setExynosMidImage(dst_img);
1444 
1445     validateFlag = validateLayer(layer_index, display, layer);
1446     if ((display->mUseDpu) &&
1447         (display->mWindowNumUsed >= display->mMaxWindowNum))
1448         validateFlag |= eInsufficientWindow;
1449 
1450     HDEBUGLOGD(eDebugResourceManager, "\t[%d] layer: validateFlag(0x%8x), supportedMPPFlag(0x%8x)",
1451             layer_index, validateFlag, layer->mSupportedMPPFlag);
1452 
1453     if (hwcCheckDebugMessages(eDebugResourceManager)) {
1454         layer->printLayer();
1455     }
1456 
1457     if ((validateFlag == NO_ERROR) || (validateFlag == eInsufficientWindow) ||
1458         (validateFlag == eDimLayer)) {
1459         bool isAssignable = false;
1460         uint64_t isSupported = 0;
1461         /* 1. Find available otfMPP */
1462         if (validateFlag != eInsufficientWindow) {
1463             for (uint32_t j = 0; j < mOtfMPPs.size(); j++) {
1464                 if ((layer->mSupportedMPPFlag & mOtfMPPs[j]->mLogicalType) != 0)
1465                     isAssignable = mOtfMPPs[j]->isAssignable(display, src_img, dst_img);
1466 
1467                 HDEBUGLOGD(eDebugResourceManager, "\t\t check %s: flag (%d) supportedBit(%d), isAssignable(%d)",
1468                         mOtfMPPs[j]->mName.string(),layer->mSupportedMPPFlag,
1469                         (layer->mSupportedMPPFlag & mOtfMPPs[j]->mLogicalType), isAssignable);
1470                 if ((layer->mSupportedMPPFlag & mOtfMPPs[j]->mLogicalType) && (isAssignable)) {
1471                     isSupported = mOtfMPPs[j]->isSupported(*display, src_img, dst_img);
1472                     HDEBUGLOGD(eDebugResourceManager, "\t\t\t isSuported(%" PRIx64 ")", -isSupported);
1473                     if (isSupported == NO_ERROR) {
1474                         *otfMPP = mOtfMPPs[j];
1475                         return HWC2_COMPOSITION_DEVICE;
1476                     }
1477                 }
1478             }
1479         }
1480 
1481         /* 2. Find available m2mMPP */
1482         for (uint32_t j = 0; j < mM2mMPPs.size(); j++) {
1483 
1484             if ((display->mUseDpu == true) &&
1485                 (mM2mMPPs[j]->mLogicalType == MPP_LOGICAL_G2D_COMBO))
1486                 continue;
1487             if ((display->mUseDpu == false) &&
1488                 (mM2mMPPs[j]->mLogicalType == MPP_LOGICAL_G2D_RGB))
1489                 continue;
1490 
1491             /* Only G2D can be assigned if layer is supported by G2D
1492              * when window is not sufficient
1493              */
1494             if ((validateFlag == eInsufficientWindow) &&
1495                 (mM2mMPPs[j]->mLogicalType != MPP_LOGICAL_G2D_RGB) &&
1496                 (mM2mMPPs[j]->mLogicalType != MPP_LOGICAL_G2D_COMBO)) {
1497                 HDEBUGLOGD(eDebugResourceManager, "\t\tInsufficient window but exynosComposition is not assigned");
1498                 continue;
1499             }
1500 
1501             bool isAssignableState = mM2mMPPs[j]->isAssignableState(display, src_img, dst_img);
1502 
1503             HDEBUGLOGD(eDebugResourceManager, "\t\t check %s: supportedBit(%d), isAssignableState(%d)",
1504                     mM2mMPPs[j]->mName.string(),
1505                     (layer->mSupportedMPPFlag & mM2mMPPs[j]->mLogicalType), isAssignableState);
1506 
1507             if (isAssignableState) {
1508                 if ((mM2mMPPs[j]->mLogicalType != MPP_LOGICAL_G2D_RGB) &&
1509                     (mM2mMPPs[j]->mLogicalType != MPP_LOGICAL_G2D_COMBO)) {
1510                     exynos_image otf_dst_img = dst_img;
1511 
1512                     otf_dst_img.format = DEFAULT_MPP_DST_FORMAT;
1513 
1514                     std::vector<exynos_image> image_lists;
1515                     if ((ret = getCandidateM2mMPPOutImages(display, layer, image_lists)) < 0)
1516                     {
1517                         HWC_LOGE(display, "Fail getCandidateM2mMPPOutImages (%d)", ret);
1518                         return ret;
1519                     }
1520                     HDEBUGLOGD(eDebugResourceManager, "candidate M2mMPPOutImage num: %zu", image_lists.size());
1521                     for (auto &otf_src_img : image_lists) {
1522                         dumpExynosImage(eDebugResourceManager, otf_src_img);
1523                         exynos_image m2m_src_img = src_img;
1524                         /* transform is already handled by m2mMPP */
1525                         if (CC_UNLIKELY(otf_src_img.transform != 0 || otf_dst_img.transform != 0)) {
1526                             ALOGE("%s:: transform should be handled by m2mMPP. otf_src_img "
1527                                   "transform %d, otf_dst_img transform %d",
1528                                   __func__, otf_src_img.transform, otf_dst_img.transform);
1529                             otf_src_img.transform = 0;
1530                             otf_dst_img.transform = 0;
1531                         }
1532 
1533                         /*
1534                          * This is the case that layer color transform should be
1535                          * addressed by otfMPP not m2mMPP
1536                          */
1537                         if (otf_src_img.needColorTransform)
1538                             m2m_src_img.needColorTransform = false;
1539 
1540                         if (((isSupported = mM2mMPPs[j]->isSupported(*display, m2m_src_img, otf_src_img)) != NO_ERROR) ||
1541                             ((isAssignable = mM2mMPPs[j]->hasEnoughCapa(display, m2m_src_img, otf_src_img)) == false))
1542                         {
1543                             HDEBUGLOGD(eDebugResourceManager, "\t\t\t check %s: supportedBit(0x%" PRIx64 "), hasEnoughCapa(%d)",
1544                                     mM2mMPPs[j]->mName.string(), -isSupported, isAssignable);
1545                             continue;
1546                         }
1547 
1548                         /* 3. Find available OtfMPP for output of m2mMPP */
1549                         for (uint32_t k = 0; k < mOtfMPPs.size(); k++) {
1550                             isSupported = mOtfMPPs[k]->isSupported(*display, otf_src_img, otf_dst_img);
1551                             isAssignable = false;
1552                             if (isSupported == NO_ERROR)
1553                                 isAssignable = mOtfMPPs[k]->isAssignable(display, otf_src_img, otf_dst_img);
1554 
1555                             HDEBUGLOGD(eDebugResourceManager, "\t\t\t check %s: supportedBit(0x%" PRIx64 "), isAssignable(%d)",
1556                                     mOtfMPPs[k]->mName.string(), -isSupported, isAssignable);
1557                             if ((isSupported == NO_ERROR) && isAssignable) {
1558                                 *m2mMPP = mM2mMPPs[j];
1559                                 *otfMPP = mOtfMPPs[k];
1560                                 m2m_out_img = otf_src_img;
1561                                 return HWC2_COMPOSITION_DEVICE;
1562                             }
1563                         }
1564                     }
1565                 } else {
1566                     if ((layer->mSupportedMPPFlag & mM2mMPPs[j]->mLogicalType) &&
1567                         ((isAssignable = mM2mMPPs[j]->hasEnoughCapa(display, src_img, dst_img) == true))) {
1568                         *m2mMPP = mM2mMPPs[j];
1569                         return HWC2_COMPOSITION_EXYNOS;
1570                     } else {
1571                         HDEBUGLOGD(eDebugResourceManager, "\t\t\t check %s: layer's mSupportedMPPFlag(0x%8x), hasEnoughCapa(%d)",
1572                                 mM2mMPPs[j]->mName.string(), layer->mSupportedMPPFlag, isAssignable);
1573                     }
1574                 }
1575             }
1576         }
1577     }
1578     /* Fail to assign resource */
1579     if (validateFlag != NO_ERROR)
1580         overlayInfo = validateFlag;
1581     else
1582         overlayInfo = eMPPUnsupported;
1583     return HWC2_COMPOSITION_CLIENT;
1584 }
1585 
assignLayers(ExynosDisplay * display,uint32_t priority)1586 int32_t ExynosResourceManager::assignLayers(ExynosDisplay * display, uint32_t priority)
1587 {
1588     HDEBUGLOGD(eDebugResourceManager, "%s:: display(%d), priority(%d) +++++",
1589             __func__, display->mType, priority);
1590 
1591     int32_t ret = NO_ERROR;
1592     bool needReAssign = false;
1593     for (uint32_t i = 0; i < display->mLayers.size(); i++) {
1594         ExynosLayer *layer = display->mLayers[i];
1595         ExynosMPP *m2mMPP = NULL;
1596         ExynosMPP *otfMPP = NULL;
1597         exynos_image m2m_out_img;
1598         uint32_t validateFlag = 0;
1599         int32_t compositionType = 0;
1600 
1601         if ((layer->mValidateCompositionType == HWC2_COMPOSITION_CLIENT) ||
1602             (layer->mValidateCompositionType == HWC2_COMPOSITION_EXYNOS))
1603             continue;
1604         if (layer->mOverlayPriority != priority)
1605             continue;
1606 
1607         exynos_image src_img;
1608         exynos_image dst_img;
1609         layer->setSrcExynosImage(&src_img);
1610         layer->setDstExynosImage(&dst_img);
1611         layer->setExynosImage(src_img, dst_img);
1612         layer->setExynosMidImage(dst_img);
1613 
1614         compositionType = assignLayer(display, layer, i, m2m_out_img, &m2mMPP, &otfMPP, validateFlag);
1615         if (compositionType == HWC2_COMPOSITION_DEVICE) {
1616             if (otfMPP != NULL) {
1617                 if ((ret = otfMPP->assignMPP(display, layer)) != NO_ERROR)
1618                 {
1619                     ALOGE("%s:: %s MPP assignMPP() error (%d)",
1620                             __func__, otfMPP->mName.string(), ret);
1621                     return ret;
1622                 }
1623                 HDEBUGLOGD(eDebugResourceManager, "\t\t[%d] layer: %s MPP is assigned",
1624                         i, otfMPP->mName.string());
1625             }
1626             if (m2mMPP != NULL) {
1627                 if ((ret = m2mMPP->assignMPP(display, layer)) != NO_ERROR)
1628                 {
1629                     ALOGE("%s:: %s MPP assignMPP() error (%d)",
1630                             __func__, m2mMPP->mName.string(), ret);
1631                     return ret;
1632                 }
1633                 layer->setExynosMidImage(m2m_out_img);
1634                 HDEBUGLOGD(eDebugResourceManager, "\t\t[%d] layer: %s MPP is assigned",
1635                         i, m2mMPP->mName.string());
1636             }
1637             layer->mValidateCompositionType = compositionType;
1638             display->mWindowNumUsed++;
1639             HDEBUGLOGD(eDebugResourceManager, "\t\t[%d] layer: mWindowNumUsed(%d)",
1640                     i, display->mWindowNumUsed);
1641         } else if (compositionType == HWC2_COMPOSITION_EXYNOS) {
1642             if (m2mMPP != NULL) {
1643                 if ((ret = m2mMPP->assignMPP(display, layer)) != NO_ERROR)
1644                 {
1645                     ALOGE("%s:: %s MPP assignMPP() error (%d)",
1646                             __func__, m2mMPP->mName.string(), ret);
1647                     return ret;
1648                 }
1649                 HDEBUGLOGD(eDebugResourceManager, "\t\t[%d] layer: %s MPP is assigned",
1650                         i, m2mMPP->mName.string());
1651             }
1652             layer->mValidateCompositionType = compositionType;
1653 
1654             HDEBUGLOGD(eDebugResourceManager, "\t\t[%d] layer: exynosComposition", i);
1655             /* G2D composition */
1656             if (((ret = display->addExynosCompositionLayer(i)) == EXYNOS_ERROR_CHANGED) ||
1657                  (ret < 0))
1658                 return ret;
1659             else {
1660                 /*
1661                  * If high fps layer should be composited by GLES then
1662                  * disable handling low fps feature and reassign resources
1663                  */
1664                 if ((display->mLowFpsLayerInfo.mHasLowFpsLayer == true) &&
1665                     (display->mClientCompositionInfo.mHasCompositionLayer == true) &&
1666                     ((display->mClientCompositionInfo.mFirstIndex < display->mLowFpsLayerInfo.mFirstIndex) ||
1667                      (display->mClientCompositionInfo.mLastIndex > display->mLowFpsLayerInfo.mLastIndex))) {
1668                     needReAssign = true;
1669                     break;
1670                 }
1671             }
1672         } else {
1673             /*
1674              * If high fps layer should be composited by GLES then
1675              * disable handling low fps feature and reassign resources
1676             */
1677             if ((display->mLowFpsLayerInfo.mHasLowFpsLayer == true) &&
1678                 (((int32_t)i < display->mLowFpsLayerInfo.mFirstIndex) ||
1679                  (display->mLowFpsLayerInfo.mLastIndex < (int32_t)i))) {
1680                 needReAssign = true;
1681                 break;
1682             }
1683 
1684             /* Fail to assign resource, set HWC2_COMPOSITION_CLIENT */
1685             if (validateFlag != NO_ERROR)
1686                 layer->mOverlayInfo |= validateFlag;
1687             else
1688                 layer->mOverlayInfo |= eMPPUnsupported;
1689 
1690             layer->mValidateCompositionType = HWC2_COMPOSITION_CLIENT;
1691             if (((ret = display->addClientCompositionLayer(i)) == EXYNOS_ERROR_CHANGED) ||
1692                 (ret < 0))
1693                 return ret;
1694         }
1695     }
1696     if (needReAssign) {
1697         if ((display->mClientCompositionInfo.mHasCompositionLayer) &&
1698                 (display->mClientCompositionInfo.mOtfMPP != NULL))
1699             display->mClientCompositionInfo.mOtfMPP->resetAssignedState();
1700 
1701         if (display->mExynosCompositionInfo.mHasCompositionLayer) {
1702             if (display->mExynosCompositionInfo.mOtfMPP != NULL)
1703                 display->mExynosCompositionInfo.mOtfMPP->resetAssignedState();
1704             if (display->mExynosCompositionInfo.mM2mMPP != NULL)
1705                 display->mExynosCompositionInfo.mM2mMPP->resetAssignedState();
1706         }
1707 
1708         display->initializeValidateInfos();
1709         display->mLowFpsLayerInfo.initializeInfos();
1710         return EXYNOS_ERROR_CHANGED;
1711     }
1712     return ret;
1713 }
1714 
assignWindow(ExynosDisplay * display)1715 int32_t ExynosResourceManager::assignWindow(ExynosDisplay *display)
1716 {
1717     HDEBUGLOGD(eDebugResourceManager, "%s +++++", __func__);
1718     int ret = NO_ERROR;
1719     uint32_t windowIndex = 0;
1720 
1721     if (!display->mUseDpu)
1722         return ret;
1723 
1724     windowIndex = display->mBaseWindowIndex;
1725 
1726     for (uint32_t i = 0; i < display->mLayers.size(); i++) {
1727         ExynosLayer *layer = display->mLayers[i];
1728         HDEBUGLOGD(eDebugResourceManager, "\t[%d] layer type: %d", i, layer->mValidateCompositionType);
1729 
1730         if (layer->mValidateCompositionType == HWC2_COMPOSITION_DEVICE) {
1731             layer->mWindowIndex = windowIndex;
1732             HDEBUGLOGD(eDebugResourceManager, "\t\t[%d] layer windowIndex: %d", i, windowIndex);
1733         } else if ((layer->mValidateCompositionType == HWC2_COMPOSITION_CLIENT) ||
1734                    (layer->mValidateCompositionType == HWC2_COMPOSITION_EXYNOS)) {
1735             ExynosCompositionInfo *compositionInfo;
1736             if (layer->mValidateCompositionType == HWC2_COMPOSITION_CLIENT)
1737                 compositionInfo = &display->mClientCompositionInfo;
1738             else
1739                 compositionInfo = &display->mExynosCompositionInfo;
1740 
1741             if ((compositionInfo->mHasCompositionLayer == false) ||
1742                 (compositionInfo->mFirstIndex < 0) ||
1743                 (compositionInfo->mLastIndex < 0)) {
1744                 HWC_LOGE(display, "%s:: Invalid %s CompositionInfo mHasCompositionLayer(%d), "
1745                         "mFirstIndex(%d), mLastIndex(%d) ",
1746                         __func__, compositionInfo->getTypeStr().string(),
1747                         compositionInfo->mHasCompositionLayer,
1748                         compositionInfo->mFirstIndex,
1749                         compositionInfo->mLastIndex);
1750                 continue;
1751             }
1752             if (i != (uint32_t)compositionInfo->mLastIndex)
1753                 continue;
1754             compositionInfo->mWindowIndex = windowIndex;
1755             HDEBUGLOGD(eDebugResourceManager, "\t\t[%d] %s Composition windowIndex: %d",
1756                     i, compositionInfo->getTypeStr().string(), windowIndex);
1757         } else {
1758             HWC_LOGE(display, "%s:: Invalid layer compositionType layer(%d), compositionType(%d)",
1759                     __func__, i, layer->mValidateCompositionType);
1760             continue;
1761         }
1762         windowIndex++;
1763     }
1764     HDEBUGLOGD(eDebugResourceManager, "%s ------", __func__);
1765     return ret;
1766 }
1767 
1768 /**
1769  * @param * display
1770  * @return int
1771  */
updateSupportedMPPFlag(ExynosDisplay * display)1772 int32_t ExynosResourceManager::updateSupportedMPPFlag(ExynosDisplay * display)
1773 {
1774     int64_t ret = 0;
1775     HDEBUGLOGD(eDebugResourceManager, "%s++++++++++", __func__);
1776     for (uint32_t i = 0; i < display->mLayers.size(); i++) {
1777         ExynosLayer *layer = display->mLayers[i];
1778         HDEBUGLOGD(eDebugResourceManager, "[%d] layer ", i);
1779 
1780         if (layer->mGeometryChanged == 0)
1781             continue;
1782 
1783         exynos_image src_img;
1784         exynos_image dst_img;
1785         exynos_image dst_img_yuv;
1786         layer->setSrcExynosImage(&src_img);
1787         layer->setDstExynosImage(&dst_img);
1788         layer->setDstExynosImage(&dst_img_yuv);
1789         dst_img.format = DEFAULT_MPP_DST_FORMAT;
1790         dst_img_yuv.format = DEFAULT_MPP_DST_YUV_FORMAT;
1791         HDEBUGLOGD(eDebugResourceManager, "\tsrc_img");
1792         dumpExynosImage(eDebugResourceManager, src_img);
1793         HDEBUGLOGD(eDebugResourceManager, "\tdst_img");
1794         dumpExynosImage(eDebugResourceManager, dst_img);
1795 
1796         /* Initialize flags */
1797         layer->mSupportedMPPFlag = 0;
1798         layer->mCheckMPPFlag.clear();
1799 
1800         /* Check OtfMPPs */
1801         for (uint32_t j = 0; j < mOtfMPPs.size(); j++) {
1802             if ((ret = mOtfMPPs[j]->isSupported(*display, src_img, dst_img)) == NO_ERROR) {
1803                 layer->mSupportedMPPFlag |= mOtfMPPs[j]->mLogicalType;
1804                 HDEBUGLOGD(eDebugResourceManager, "\t%s: supported", mOtfMPPs[j]->mName.string());
1805             } else {
1806                 if (((-ret) == eMPPUnsupportedFormat) &&
1807                     ((ret = mOtfMPPs[j]->isSupported(*display, src_img, dst_img_yuv)) == NO_ERROR)) {
1808                     layer->mSupportedMPPFlag |= mOtfMPPs[j]->mLogicalType;
1809                     HDEBUGLOGD(eDebugResourceManager, "\t%s: supported with yuv dst", mOtfMPPs[j]->mName.string());
1810                 }
1811             }
1812             if (ret < 0) {
1813                 HDEBUGLOGD(eDebugResourceManager, "\t%s: unsupported flag(0x%" PRIx64 ")", mOtfMPPs[j]->mName.string(), -ret);
1814                 uint64_t checkFlag = 0x0;
1815                 if (layer->mCheckMPPFlag.find(mOtfMPPs[j]->mLogicalType) !=
1816                         layer->mCheckMPPFlag.end()) {
1817                     checkFlag = layer->mCheckMPPFlag.at(mOtfMPPs[j]->mLogicalType);
1818                 }
1819                 checkFlag |= (-ret);
1820                 layer->mCheckMPPFlag[mOtfMPPs[j]->mLogicalType] = checkFlag;
1821             }
1822         }
1823 
1824         /* Check M2mMPPs */
1825         for (uint32_t j = 0; j < mM2mMPPs.size(); j++) {
1826             if ((ret = mM2mMPPs[j]->isSupported(*display, src_img, dst_img)) == NO_ERROR) {
1827                 layer->mSupportedMPPFlag |= mM2mMPPs[j]->mLogicalType;
1828                 HDEBUGLOGD(eDebugResourceManager, "\t%s: supported", mM2mMPPs[j]->mName.string());
1829             } else {
1830                 if (((-ret) == eMPPUnsupportedFormat) &&
1831                     ((ret = mM2mMPPs[j]->isSupported(*display, src_img, dst_img_yuv)) == NO_ERROR)) {
1832                     layer->mSupportedMPPFlag |= mM2mMPPs[j]->mLogicalType;
1833                     HDEBUGLOGD(eDebugResourceManager, "\t%s: supported with yuv dst", mM2mMPPs[j]->mName.string());
1834                 }
1835             }
1836             if (ret < 0) {
1837                 HDEBUGLOGD(eDebugResourceManager, "\t%s: unsupported flag(0x%" PRIx64 ")", mM2mMPPs[j]->mName.string(), -ret);
1838                 uint64_t checkFlag = 0x0;
1839                 if (layer->mCheckMPPFlag.find(mM2mMPPs[j]->mLogicalType) !=
1840                         layer->mCheckMPPFlag.end()) {
1841                     checkFlag = layer->mCheckMPPFlag.at(mM2mMPPs[j]->mLogicalType);
1842                 }
1843                 checkFlag |= (-ret);
1844                 layer->mCheckMPPFlag[mM2mMPPs[j]->mLogicalType] = checkFlag;
1845             }
1846         }
1847         HDEBUGLOGD(eDebugResourceManager, "[%d] layer mSupportedMPPFlag(0x%8x)", i, layer->mSupportedMPPFlag);
1848     }
1849     HDEBUGLOGD(eDebugResourceManager, "%s-------------", __func__);
1850 
1851     return NO_ERROR;
1852 }
1853 
resetResources()1854 int32_t ExynosResourceManager::resetResources()
1855 {
1856     HDEBUGLOGD(eDebugResourceManager, "%s+++++++++", __func__);
1857 
1858     for (uint32_t i = 0; i < mOtfMPPs.size(); i++) {
1859         mOtfMPPs[i]->resetMPP();
1860         if (hwcCheckDebugMessages(eDebugResourceManager)) {
1861             String8 dumpMPP;
1862             mOtfMPPs[i]->dump(dumpMPP);
1863             HDEBUGLOGD(eDebugResourceManager, "%s", dumpMPP.string());
1864         }
1865     }
1866     for (uint32_t i = 0; i < mM2mMPPs.size(); i++) {
1867         mM2mMPPs[i]->resetMPP();
1868         if (hwcCheckDebugMessages(eDebugResourceManager)) {
1869             String8 dumpMPP;
1870             mM2mMPPs[i]->dump(dumpMPP);
1871             HDEBUGLOGD(eDebugResourceManager, "%s", dumpMPP.string());
1872         }
1873     }
1874 
1875     HDEBUGLOGD(eDebugResourceManager, "%s-----------",  __func__);
1876     return NO_ERROR;
1877 }
1878 
preAssignResources()1879 int32_t ExynosResourceManager::preAssignResources()
1880 {
1881     HDEBUGLOGD(eDebugResourceManager, "%s+++++++++", __func__);
1882     uint32_t displayMode = mDevice->mDisplayMode;
1883 
1884     for (uint32_t i = 0; i < mOtfMPPs.size(); i++) {
1885         if (mOtfMPPs[i]->mEnable == false) {
1886             mOtfMPPs[i]->reserveMPP();
1887             continue;
1888         }
1889 
1890         if (mOtfMPPs[i]->mPreAssignDisplayList[displayMode] != 0) {
1891             HDEBUGLOGD(eDebugResourceManager, "\t%s check, dispMode(%d), 0x%8x", mOtfMPPs[i]->mName.string(), displayMode, mOtfMPPs[i]->mPreAssignDisplayList[displayMode]);
1892 
1893             ExynosDisplay *display = NULL;
1894             for (size_t j = 0; j < mDevice->mDisplays.size(); j++) {
1895                 display = mDevice->mDisplays[j];
1896                 if (display == nullptr)
1897                     continue;
1898                 int checkBit = mOtfMPPs[i]->mPreAssignDisplayList[displayMode] & display->getDisplayPreAssignBit();
1899                 HDEBUGLOGD(eDebugResourceManager, "\t\tdisplay index(%zu), checkBit(%d)", j, checkBit);
1900                 if (checkBit) {
1901                     HDEBUGLOGD(eDebugResourceManager, "\t\tdisplay index(%zu), displayId(%d), display(%p)", j, display->mDisplayId, display);
1902                     if (display->mDisplayControl.forceReserveMPP ||
1903                         (display->mPlugState &&
1904                          ((display->mType != HWC_DISPLAY_PRIMARY) ||
1905                           (display->mPowerModeState != HWC2_POWER_MODE_OFF)))) {
1906                         HDEBUGLOGD(eDebugResourceManager, "\t\treserve to display %d", display->mDisplayId);
1907                         mOtfMPPs[i]->reserveMPP(display->mDisplayId);
1908                         break;
1909                     }
1910                 }
1911             }
1912         }
1913     }
1914     for (uint32_t i = 0; i < mM2mMPPs.size(); i++) {
1915         if (mM2mMPPs[i]->mEnable == false) {
1916             mM2mMPPs[i]->reserveMPP();
1917             continue;
1918         }
1919 
1920         if (mResourceReserved & mM2mMPPs[i]->mLogicalType) {
1921             /* MSC can't be used for rendering */
1922             HDEBUGLOGD(eDebugResourceManager, "\t\tMPP_MSC reserve without display because preview is running");
1923             mM2mMPPs[i]->reserveMPP();
1924             continue;
1925         }
1926         HDEBUGLOGD(eDebugResourceManager, "\t%s check, 0x%8x", mM2mMPPs[i]->mName.string(), mM2mMPPs[i]->mPreAssignDisplayList[displayMode]);
1927         if (mM2mMPPs[i]->mPreAssignDisplayList[displayMode] != 0) {
1928             ExynosDisplay *display = NULL;
1929             for (size_t j = 0; j < mDevice->mDisplays.size(); j++) {
1930                 display = mDevice->mDisplays[j];
1931                 int checkBit = mM2mMPPs[i]->mPreAssignDisplayList[displayMode] & display->getDisplayPreAssignBit();
1932                 HDEBUGLOGD(eDebugResourceManager, "\t\tdisplay index(%zu), checkBit(%d)", j, checkBit);
1933                 if (checkBit) {
1934                     HDEBUGLOGD(eDebugResourceManager, "\t\tdisplay index(%zu), displayId(%d), display(%p)", j, display->mDisplayId, display);
1935                     if ((display != NULL) && (display->mPlugState == true)) {
1936                         HDEBUGLOGD(eDebugResourceManager, "\t\treserve to display %d", display->mDisplayId);
1937                         mM2mMPPs[i]->reserveMPP(display->mDisplayId);
1938                         break;
1939                     } else {
1940                         HDEBUGLOGD(eDebugResourceManager, "\t\treserve without display");
1941                         mM2mMPPs[i]->reserveMPP();
1942                     }
1943                 }
1944             }
1945         }
1946     }
1947     for (uint32_t i = 0; i < mOtfMPPs.size(); i++) {
1948         if (hwcCheckDebugMessages(eDebugResourceManager)) {
1949             String8 dumpMPP;
1950             mOtfMPPs[i]->dump(dumpMPP);
1951             HDEBUGLOGD(eDebugResourceManager, "%s", dumpMPP.string());
1952         }
1953     }
1954     for (uint32_t i = 0; i < mM2mMPPs.size(); i++) {
1955         if (hwcCheckDebugMessages(eDebugResourceManager)) {
1956             String8 dumpMPP;
1957             mM2mMPPs[i]->dump(dumpMPP);
1958             HDEBUGLOGD(eDebugResourceManager, "%s", dumpMPP.string());
1959         }
1960     }
1961     HDEBUGLOGD(eDebugResourceManager, "%s-----------",  __func__);
1962     return NO_ERROR;
1963 }
1964 
preAssignWindows()1965 void ExynosResourceManager::preAssignWindows()
1966 {
1967     ExynosDisplay *display = NULL;
1968     ExynosPrimaryDisplayModule *primaryDisplay =
1969         (ExynosPrimaryDisplayModule *)mDevice->getDisplay(getDisplayId(HWC_DISPLAY_PRIMARY, 0));
1970     primaryDisplay->usePreDefinedWindow(false);
1971 
1972     for (size_t i = 1; i < mDevice->mDisplays.size(); i++) {
1973         display = mDevice->mDisplays[i];
1974         if ((display == NULL) || (display->mType != HWC_DISPLAY_EXTERNAL))
1975             continue;
1976         if (display->mPlugState == true) {
1977             primaryDisplay->usePreDefinedWindow(true);
1978         }
1979     }
1980 }
1981 
preProcessLayer(ExynosDisplay * display)1982 int32_t ExynosResourceManager::preProcessLayer(ExynosDisplay * display)
1983 {
1984     int32_t ret = 0;
1985     hasHdrLayer = false;
1986     hasDrmLayer = false;
1987 
1988     for (uint32_t i = 0; i < display->mLayers.size(); i++) {
1989         ExynosLayer *layer = display->mLayers[i];
1990         if ((ret = layer->doPreProcess()) < 0) {
1991             HWC_LOGE(display, "%s:: doPreProcess() error, display(%d), layer %d", __func__, display->mType, i);
1992             return ret;
1993         }
1994         /* mIsHdrLayer is known after preprocess */
1995         if (layer->mIsHdrLayer) hasHdrLayer = true;
1996         if ((layer->mLayerBuffer != NULL) && (getDrmMode(layer->mLayerBuffer) != NO_DRM))
1997             hasDrmLayer = true;
1998     }
1999 
2000     // Re-align layer priority for max overlay resources
2001     uint32_t mNumMaxPriorityLayers = 0;
2002     for (int i = (display->mLayers.size()-1); i >= 0; i--) {
2003         ExynosLayer *layer = display->mLayers[i];
2004         HDEBUGLOGD(eDebugResourceManager, "Priority align: i:%d, layer priority:%d, Max:%d, mNumMaxPriorityAllowed:%d", i,
2005                 layer->mOverlayPriority, mNumMaxPriorityLayers, display->mNumMaxPriorityAllowed);
2006         if (layer->mOverlayPriority == ePriorityMax) {
2007             if (mNumMaxPriorityLayers >= display->mNumMaxPriorityAllowed) {
2008                 layer->mOverlayPriority = ePriorityHigh;
2009             }
2010             mNumMaxPriorityLayers++;
2011         }
2012     }
2013 
2014     return NO_ERROR;
2015 }
2016 
getExynosMPP(uint32_t type)2017 ExynosMPP* ExynosResourceManager::getExynosMPP(uint32_t type)
2018 {
2019     for (uint32_t i = 0; i < mOtfMPPs.size(); i++) {
2020         if (mOtfMPPs[i]->mLogicalType == type)
2021             return mOtfMPPs[i];
2022     }
2023     for (uint32_t i = 0; i < mM2mMPPs.size(); i++) {
2024         if (mM2mMPPs[i]->mLogicalType == type)
2025             return mM2mMPPs[i];
2026     }
2027 
2028     return NULL;
2029 }
2030 
getExynosMPP(uint32_t physicalType,uint32_t physicalIndex)2031 ExynosMPP* ExynosResourceManager::getExynosMPP(uint32_t physicalType, uint32_t physicalIndex)
2032 {
2033     for (uint32_t i = 0; i < mOtfMPPs.size(); i++) {
2034         if ((mOtfMPPs[i]->mPhysicalType == physicalType) &&
2035             (mOtfMPPs[i]->mPhysicalIndex == physicalIndex))
2036             return mOtfMPPs[i];
2037     }
2038     for (uint32_t i = 0; i < mM2mMPPs.size(); i++) {
2039         if ((mM2mMPPs[i]->mPhysicalType == physicalType) &&
2040             (mM2mMPPs[i]->mPhysicalIndex == physicalIndex))
2041             return mM2mMPPs[i];
2042     }
2043 
2044     return NULL;
2045 }
2046 
updateResourceState()2047 int32_t ExynosResourceManager::updateResourceState()
2048 {
2049     for (uint32_t i = 0; i < mOtfMPPs.size(); i++) {
2050         if (mOtfMPPs[i]->mAssignedSources.size() == 0)
2051             mOtfMPPs[i]->requestHWStateChange(MPP_HW_STATE_IDLE);
2052         mOtfMPPs[i]->mPrevAssignedState = mOtfMPPs[i]->mAssignedState;
2053     }
2054     for (uint32_t i = 0; i < mM2mMPPs.size(); i++) {
2055         if (mM2mMPPs[i]->mAssignedSources.size() == 0)
2056             mM2mMPPs[i]->requestHWStateChange(MPP_HW_STATE_IDLE);
2057         mM2mMPPs[i]->mPrevAssignedState = mM2mMPPs[i]->mAssignedState;
2058     }
2059     return NO_ERROR;
2060 }
2061 
2062 /*
2063  * This function is called every frame.
2064  * This base function does nothing.
2065  * Module that supports setting frame rate should implement this function
2066  * in the module source code (hardware/samsung_slsi/graphics/exynos...).
2067  */
setFrameRateForPerformance(ExynosMPP & mpp,AcrylicPerformanceRequestFrame * frame)2068 void ExynosResourceManager::setFrameRateForPerformance(ExynosMPP &mpp,
2069         AcrylicPerformanceRequestFrame *frame)
2070 {
2071     int fps = ceil(msecsPerSec / mpp.mCapacity);
2072     HDEBUGLOGD(eDebugResourceAssigning, "%s setFrameRate %d",
2073             mpp.mName.string(), fps);
2074     frame->setFrameRate(fps);
2075 }
2076 
deliverPerformanceInfo()2077 int32_t ExynosResourceManager::deliverPerformanceInfo()
2078 {
2079     int ret = NO_ERROR;
2080     for (uint32_t mpp_physical_type = 0; mpp_physical_type < MPP_P_TYPE_MAX; mpp_physical_type++) {
2081         /* Only G2D gets performance info in current version */
2082         if (mpp_physical_type != MPP_G2D)
2083             continue;
2084         AcrylicPerformanceRequest request;
2085         uint32_t assignedInstanceNum = 0;
2086         uint32_t assignedInstanceIndex = 0;
2087         ExynosMPP *mpp = NULL;
2088         bool canSkipSetting = true;
2089 
2090         for (uint32_t i = 0; i < mM2mMPPs.size(); i++) {
2091             mpp = mM2mMPPs[i];
2092             if (mpp->mPhysicalType != mpp_physical_type)
2093                 continue;
2094             /* Performance setting can be skipped
2095              * if all of instance's mPrevAssignedState, mAssignedState
2096              * are MPP_ASSIGN_STATE_FREE
2097              */
2098             if ((mpp->mPrevAssignedState & MPP_ASSIGN_STATE_ASSIGNED) ||
2099                 (mpp->mAssignedState & MPP_ASSIGN_STATE_ASSIGNED))
2100             {
2101                 canSkipSetting = false;
2102             }
2103 
2104             if (mpp->canSkipProcessing())
2105                 continue;
2106 
2107             if ((mpp->mAssignedDisplay != NULL) &&
2108                 (mpp->mAssignedSources.size() > 0))
2109             {
2110                 assignedInstanceNum++;
2111             }
2112         }
2113         if ((canSkipSetting == true) && (assignedInstanceNum != 0)) {
2114             HWC_LOGE(NULL, "%s:: canSKip true but assignedInstanceNum(%d)",
2115                     __func__, assignedInstanceNum);
2116         }
2117         request.reset(assignedInstanceNum);
2118 
2119         if (canSkipSetting == true)
2120             continue;
2121 
2122         for (uint32_t i = 0; i < mM2mMPPs.size(); i++) {
2123             mpp = mM2mMPPs[i];
2124             if ((mpp->mPhysicalType == mpp_physical_type) &&
2125                 (mpp->mAssignedDisplay != NULL) &&
2126                 (mpp->mAssignedSources.size() > 0))
2127             {
2128                 if (mpp->canSkipProcessing())
2129                     continue;
2130                 if (assignedInstanceIndex >= assignedInstanceNum) {
2131                     HWC_LOGE(NULL,"assignedInstanceIndex error (%d, %d)", assignedInstanceIndex, assignedInstanceNum);
2132                     break;
2133                 }
2134                 AcrylicPerformanceRequestFrame *frame = request.getFrame(assignedInstanceIndex);
2135                 if(frame->reset(mpp->mAssignedSources.size()) == false) {
2136                     HWC_LOGE(NULL,"%d frame reset fail (%zu)", assignedInstanceIndex, mpp->mAssignedSources.size());
2137                     break;
2138                 }
2139                 setFrameRateForPerformance(*mpp, frame);
2140 
2141                 for (uint32_t j = 0; j < mpp->mAssignedSources.size(); j++) {
2142                     ExynosMPPSource* mppSource = mpp->mAssignedSources[j];
2143                     frame->setSourceDimension(j,
2144                             mppSource->mSrcImg.w, mppSource->mSrcImg.h,
2145                             mppSource->mSrcImg.format);
2146 
2147                     if (mppSource->mSrcImg.compressed == 1)
2148                         frame->setAttribute(j, AcrylicCanvas::ATTR_COMPRESSED);
2149 
2150                     hwc_rect_t src_area;
2151                     src_area.left = mppSource->mSrcImg.x;
2152                     src_area.top = mppSource->mSrcImg.y;
2153                     src_area.right = mppSource->mSrcImg.x + mppSource->mSrcImg.w;
2154                     src_area.bottom = mppSource->mSrcImg.y + mppSource->mSrcImg.h;
2155 
2156                     hwc_rect_t out_area;
2157                     out_area.left = mppSource->mMidImg.x;
2158                     out_area.top = mppSource->mMidImg.y;
2159                     out_area.right = mppSource->mMidImg.x + mppSource->mMidImg.w;
2160                     out_area.bottom = mppSource->mMidImg.y + mppSource->mMidImg.h;
2161 
2162                     frame->setTransfer(j, src_area, out_area, mppSource->mSrcImg.transform);
2163                 }
2164                 uint32_t format = mpp->mAssignedSources[0]->mMidImg.format;
2165                 bool hasSolidColorLayer = false;
2166                 if (mpp->mNeedSolidColorLayer) {
2167                     format = DEFAULT_MPP_DST_FORMAT;
2168                     hasSolidColorLayer = true;
2169                 }
2170 
2171                 frame->setTargetDimension(mpp->mAssignedDisplay->mXres,
2172                         mpp->mAssignedDisplay->mYres, format, hasSolidColorLayer);
2173 
2174                 assignedInstanceIndex++;
2175             }
2176         }
2177         if ((mpp = getExynosMPP(MPP_LOGICAL_G2D_RGB)) != NULL)
2178             mpp->mAcrylicHandle->requestPerformanceQoS(&request);
2179         else
2180             HWC_LOGE(NULL,"getExynosMPP(MPP_LOGICAL_G2D_RGB) failed");
2181     }
2182     return ret;
2183 }
2184 
2185 /*
2186  * Get used capacity of the resource that abstracts same HW resource
2187  * but it is different instance with mpp
2188  */
getResourceUsedCapa(ExynosMPP & mpp)2189 float ExynosResourceManager::getResourceUsedCapa(ExynosMPP &mpp)
2190 {
2191     float usedCapa = 0;
2192     if (mpp.mCapacity < 0)
2193         return usedCapa;
2194 
2195     HDEBUGLOGD(eDebugResourceManager, "%s:: [%s][%d] mpp[%d, %d]",
2196             __func__, mpp.mName.string(), mpp.mLogicalIndex,
2197             mpp.mPhysicalType, mpp.mPhysicalIndex);
2198 
2199     if (mpp.mMPPType == MPP_TYPE_OTF) {
2200         for (uint32_t i = 0; i < mOtfMPPs.size(); i++) {
2201             if ((mpp.mPhysicalType == mOtfMPPs[i]->mPhysicalType) &&
2202                 (mpp.mPhysicalIndex == mOtfMPPs[i]->mPhysicalIndex)) {
2203                 usedCapa += mOtfMPPs[i]->mUsedCapacity;
2204             }
2205         }
2206     } else {
2207         for (uint32_t i = 0; i < mM2mMPPs.size(); i++) {
2208             if ((mpp.mPhysicalType == mM2mMPPs[i]->mPhysicalType) &&
2209                 (mpp.mPhysicalIndex == mM2mMPPs[i]->mPhysicalIndex)) {
2210                 usedCapa += mM2mMPPs[i]->mUsedCapacity;
2211             }
2212         }
2213     }
2214 
2215     HDEBUGLOGD(eDebugResourceManager, "\t[%s][%d] mpp usedCapa: %f",
2216             mpp.mName.string(), mpp.mLogicalIndex, usedCapa);
2217     return usedCapa;
2218 }
2219 
enableMPP(uint32_t physicalType,uint32_t physicalIndex,uint32_t logicalIndex,uint32_t enable)2220 void ExynosResourceManager::enableMPP(uint32_t physicalType, uint32_t physicalIndex, uint32_t logicalIndex, uint32_t enable)
2221 {
2222     for (uint32_t i = 0; i < mOtfMPPs.size(); i++) {
2223         if ((mOtfMPPs[i]->mPhysicalType == physicalType) &&
2224             (mOtfMPPs[i]->mPhysicalIndex == physicalIndex) &&
2225             (mOtfMPPs[i]->mLogicalIndex == logicalIndex)) {
2226             mOtfMPPs[i]->mEnable = !!(enable);
2227             return;
2228         }
2229     }
2230 
2231     for (uint32_t i = 0; i < mM2mMPPs.size(); i++) {
2232         if ((mM2mMPPs[i]->mPhysicalType == physicalType) &&
2233             (mM2mMPPs[i]->mPhysicalIndex == physicalIndex) &&
2234             (mM2mMPPs[i]->mLogicalIndex == logicalIndex)) {
2235             mM2mMPPs[i]->mEnable = !!(enable);
2236             return;
2237         }
2238     }
2239 }
2240 
setScaleDownRatio(uint32_t physicalType,uint32_t physicalIndex,uint32_t logicalIndex,uint32_t scaleDownRatio)2241 void ExynosResourceManager::setScaleDownRatio(uint32_t physicalType,
2242         uint32_t physicalIndex, uint32_t logicalIndex, uint32_t scaleDownRatio)
2243 {
2244     ExynosMPP *findMpp = nullptr;
2245 
2246     auto mpp_compare = [=](ExynosMPP *mpp)->bool {
2247         return ((mpp->mPhysicalType == physicalType) &&
2248                 (mpp->mPhysicalIndex == physicalIndex) &&
2249                 (mpp->mLogicalIndex == logicalIndex));
2250     };
2251 
2252     auto otfMPP = std::find_if(mOtfMPPs.begin(), mOtfMPPs.end(),
2253             mpp_compare);
2254     if (otfMPP != mOtfMPPs.end()) {
2255         findMpp = *otfMPP;
2256     } else {
2257         auto m2mMPP = std::find_if(mM2mMPPs.begin(), mM2mMPPs.end(),
2258                 mpp_compare);
2259         findMpp = m2mMPP == mM2mMPPs.end() ? nullptr : *m2mMPP;
2260     }
2261 
2262     if (findMpp == nullptr) {
2263         ALOGE("%s:: Invalid mpp (type: %d, index: %d, %d)",
2264                 __func__, physicalType, physicalIndex, logicalIndex);
2265         return;
2266     }
2267     for (uint32_t i = RESTRICTION_RGB; i < RESTRICTION_MAX; i++) {
2268         findMpp->mDstSizeRestrictions[i].maxDownScale = scaleDownRatio;
2269     }
2270 }
2271 
prepareResources()2272 int32_t  ExynosResourceManager::prepareResources()
2273 {
2274     int ret = NO_ERROR;
2275     HDEBUGLOGD(eDebugResourceManager, "This is first validate");
2276     if ((ret = resetResources()) != NO_ERROR) {
2277         HWC_LOGE(NULL,"%s:: resetResources() error (%d)",
2278                 __func__, ret);
2279         return ret;
2280     }
2281     if ((ret = preAssignResources()) != NO_ERROR) {
2282         HWC_LOGE(NULL,"%s:: preAssignResources() error (%d)",
2283                 __func__, ret);
2284         return ret;
2285     }
2286 
2287 	return ret;
2288 }
2289 
finishAssignResourceWork()2290 int32_t ExynosResourceManager::finishAssignResourceWork()
2291 {
2292 	int ret = NO_ERROR;
2293     if ((ret = updateResourceState()) != NO_ERROR) {
2294         HWC_LOGE(NULL,"%s:: stopUnAssignedResource() error (%d)",
2295                 __func__, ret);
2296         return ret;
2297     }
2298 
2299     mDevice->clearGeometryChanged();
2300     return ret;
2301 }
2302 
initResourcesState(ExynosDisplay * display)2303 int32_t ExynosResourceManager::initResourcesState(ExynosDisplay *display)
2304 {
2305     int ret = 0;
2306 
2307     if (mDevice->isFirstValidate()) {
2308         HDEBUGLOGD(eDebugResourceManager, "This is first validate");
2309         if (exynosHWCControl.displayMode < DISPLAY_MODE_NUM)
2310             mDevice->mDisplayMode = exynosHWCControl.displayMode;
2311 
2312         if ((ret = prepareResources()) != NO_ERROR) {
2313             HWC_LOGE(display, "%s:: prepareResources() error (%d)",
2314                     __func__, ret);
2315             return ret;
2316         }
2317         preAssignWindows();
2318 
2319     }
2320 
2321     return NO_ERROR;
2322 }
2323 
makeSizeRestrictions(uint32_t mppId,const restriction_size_t & size,restriction_classification_t format)2324 void ExynosResourceManager::makeSizeRestrictions(uint32_t mppId, const restriction_size_t &size,
2325                                                  restriction_classification_t format) {
2326     mSizeRestrictions[format][mSizeRestrictionCnt[format]].key.hwType = static_cast<mpp_phycal_type_t>(mppId);
2327     mSizeRestrictions[format][mSizeRestrictionCnt[format]].key.nodeType = NODE_SRC;
2328     mSizeRestrictions[format][mSizeRestrictionCnt[format]].key.format = HAL_PIXEL_FORMAT_NONE;
2329     mSizeRestrictions[format][mSizeRestrictionCnt[format]].key.reserved = 0;
2330     mSizeRestrictions[format][mSizeRestrictionCnt[format]++].sizeRestriction = size;
2331 
2332     mSizeRestrictions[format][mSizeRestrictionCnt[format]].key.hwType = static_cast<mpp_phycal_type_t>(mppId);
2333     mSizeRestrictions[format][mSizeRestrictionCnt[format]].key.nodeType = NODE_DST;
2334     mSizeRestrictions[format][mSizeRestrictionCnt[format]].key.format = HAL_PIXEL_FORMAT_NONE;
2335     mSizeRestrictions[format][mSizeRestrictionCnt[format]].key.reserved = 0;
2336     mSizeRestrictions[format][mSizeRestrictionCnt[format]++].sizeRestriction = size;
2337 
2338     HDEBUGLOGD(eDebugDefault, "MPP : %s, %d, %d, %d, %d, %d, %d, %d, %d, %d, %d, %d, %d, %d, %d, %d, %d",
2339             getMPPStr(mppId).string(),
2340             size.maxDownScale,
2341             size.maxUpScale,
2342             size.maxFullWidth,
2343             size.maxFullHeight,
2344             size.minFullWidth,
2345             size.minFullHeight,
2346             size.fullWidthAlign,
2347             size.fullHeightAlign,
2348             size.maxCropWidth,
2349             size.maxCropHeight,
2350             size.minCropWidth,
2351             size.minCropHeight,
2352             size.cropXAlign,
2353             size.cropYAlign,
2354             size.cropWidthAlign,
2355             size.cropHeightAlign);
2356 }
2357 
makeFormatRestrictions(restriction_key_t table)2358 void ExynosResourceManager::makeFormatRestrictions(restriction_key_t table) {
2359 
2360     mFormatRestrictions[mFormatRestrictionCnt] = table;
2361 
2362     HDEBUGLOGD(eDebugDefault, "MPP : %s, %d, %s, %d",
2363                getMPPStr(mFormatRestrictions[mFormatRestrictionCnt].hwType).string(),
2364                mFormatRestrictions[mFormatRestrictionCnt].nodeType,
2365                getFormatStr(mFormatRestrictions[mFormatRestrictionCnt].format, COMP_ANY).string(),
2366                mFormatRestrictions[mFormatRestrictionCnt].reserved);
2367     mFormatRestrictionCnt++;
2368 }
2369 
makeAcrylRestrictions(mpp_phycal_type_t type)2370 void ExynosResourceManager::makeAcrylRestrictions(mpp_phycal_type_t type){
2371 
2372     Acrylic *arc = NULL;
2373     const HW2DCapability *cap;
2374 
2375     if (type == MPP_MSC)
2376         arc = Acrylic::createScaler();
2377     else if (type == MPP_G2D)
2378         arc = Acrylic::createCompositor();
2379     else {
2380         ALOGE("Unknown MPP");
2381         return;
2382     }
2383 
2384     cap = &arc->getCapabilities();
2385 
2386     /* format restriction */
2387     std::unordered_set<int32_t> supportedHalFormats;
2388     for (uint32_t i = 0; i < FORMAT_MAX_CNT; i++) {
2389         if (cap->isFormatSupported(exynos_format_desc[i].halFormat)) {
2390             /* Not add same hal pixel format */
2391             if (supportedHalFormats.find(exynos_format_desc[i].halFormat) !=
2392                     supportedHalFormats.end())
2393                 continue;
2394             restriction_key_t queried_format;
2395             queried_format.hwType = type;
2396             queried_format.nodeType = NODE_NONE;
2397             queried_format.format = exynos_format_desc[i].halFormat;
2398             queried_format.reserved = 0;
2399             makeFormatRestrictions(queried_format);
2400             supportedHalFormats.insert(exynos_format_desc[i].halFormat);
2401         }
2402     }
2403 
2404     /* RGB size restrictions */
2405     restriction_size rSize;
2406     rSize.maxDownScale = cap->supportedMinMinification().hori;
2407     rSize.maxUpScale = cap->supportedMaxMagnification().hori;
2408     rSize.maxFullWidth = cap->supportedMaxSrcDimension().hori;
2409     rSize.maxFullHeight = cap->supportedMaxSrcDimension().vert;
2410     rSize.minFullWidth = cap->supportedMinSrcDimension().hori;
2411     rSize.minFullHeight = cap->supportedMinSrcDimension().vert;
2412     rSize.fullWidthAlign = cap->supportedDimensionAlign().hori;
2413     rSize.fullHeightAlign = cap->supportedDimensionAlign().vert;
2414     rSize.maxCropWidth = cap->supportedMaxSrcDimension().hori;
2415     rSize.maxCropHeight = cap->supportedMaxSrcDimension().vert;
2416     rSize.minCropWidth = cap->supportedMinSrcDimension().hori;
2417     rSize.minCropHeight = cap->supportedMinSrcDimension().vert;
2418     rSize.cropXAlign = cap->supportedDimensionAlign().hori;
2419     rSize.cropYAlign = cap->supportedDimensionAlign().vert;
2420     rSize.cropWidthAlign = cap->supportedDimensionAlign().hori;
2421     rSize.cropHeightAlign = cap->supportedDimensionAlign().vert;
2422 
2423     makeSizeRestrictions(type, rSize, RESTRICTION_RGB);
2424 
2425     /* YUV size restrictions */
2426     rSize.fullWidthAlign = max(static_cast<uint32_t>(cap->supportedDimensionAlign().hori),
2427             YUV_CHROMA_H_SUBSAMPLE);
2428     rSize.fullHeightAlign = max(static_cast<uint32_t>(cap->supportedDimensionAlign().vert),
2429             YUV_CHROMA_V_SUBSAMPLE);
2430     rSize.cropXAlign = max(static_cast<uint32_t>(cap->supportedDimensionAlign().hori),
2431             YUV_CHROMA_H_SUBSAMPLE);
2432     rSize.cropYAlign = max(static_cast<uint32_t>(cap->supportedDimensionAlign().vert),
2433             YUV_CHROMA_V_SUBSAMPLE);
2434     rSize.cropWidthAlign = max(static_cast<uint32_t>(cap->supportedDimensionAlign().hori),
2435             YUV_CHROMA_H_SUBSAMPLE);
2436     rSize.cropHeightAlign = max(static_cast<uint32_t>(cap->supportedDimensionAlign().vert),
2437             YUV_CHROMA_V_SUBSAMPLE);
2438 
2439     makeSizeRestrictions(type, rSize, RESTRICTION_YUV);
2440 
2441     delete arc;
2442 }
2443 
getPhysicalType(int ch) const2444 mpp_phycal_type_t ExynosResourceManager::getPhysicalType(int ch) const {
2445 
2446     for (int i=0; i < MAX_DECON_DMA_TYPE; i++){
2447         if(IDMA_CHANNEL_MAP[i].channel == ch)
2448             return IDMA_CHANNEL_MAP[i].type;
2449     }
2450 
2451     return MPP_P_TYPE_MAX;
2452 }
2453 
getOtfMPPWithChannel(int ch)2454 ExynosMPP* ExynosResourceManager::getOtfMPPWithChannel(int ch)
2455 {
2456     ExynosMPP *otfMPP = NULL;
2457 
2458     for (int i=0; i < MAX_DECON_DMA_TYPE; i++){
2459         if(IDMA_CHANNEL_MAP[i].channel == ch) {
2460             otfMPP = getExynosMPP(IDMA_CHANNEL_MAP[i].type, IDMA_CHANNEL_MAP[i].index);
2461             break;
2462         }
2463     }
2464     return otfMPP;
2465 }
2466 
updateRestrictions()2467 void ExynosResourceManager::updateRestrictions() {
2468 
2469     if (mDevice->mDeviceInterface->getUseQuery() == true) {
2470         std::unordered_set<uint32_t> checkDuplicateMPP;
2471         for (const auto unit: AVAILABLE_M2M_MPP_UNITS) {
2472             if (checkDuplicateMPP.find(unit.physicalType) ==
2473                     checkDuplicateMPP.end())  {
2474                 makeAcrylRestrictions(static_cast<mpp_phycal_type_t>(unit.physicalType));
2475                 checkDuplicateMPP.insert(unit.physicalType);
2476             }
2477         }
2478     } else {
2479         mFormatRestrictionCnt = sizeof(restriction_format_table)/sizeof(restriction_key);
2480         for (uint32_t i = 0 ; i < mFormatRestrictionCnt; i++) {
2481             mFormatRestrictions[i].hwType = restriction_format_table[i].hwType;
2482             mFormatRestrictions[i].nodeType = restriction_format_table[i].nodeType;
2483             mFormatRestrictions[i].format = restriction_format_table[i].format;
2484             mFormatRestrictions[i].reserved = restriction_format_table[i].reserved;
2485         }
2486 
2487         // i = RGB, YUV
2488         // j = Size restriction count for each format (YUV, RGB)
2489         for (uint32_t i = 0; i < sizeof(restriction_tables)/sizeof(restriction_table_element); i++) {
2490             mSizeRestrictionCnt[i] = restriction_tables[i].table_element_size;
2491             for (uint32_t j = 0; j < mSizeRestrictionCnt[i]; j++) {
2492                 memcpy(&mSizeRestrictions[i][j], &restriction_tables[i].table[j],
2493                         sizeof(mSizeRestrictions[i][j]));
2494             }
2495         }
2496     }
2497 
2498     for (uint32_t i = 0; i < mOtfMPPs.size(); i++) {
2499         // mAttr should be updated with updated feature_table
2500         mOtfMPPs[i]->updateAttr();
2501         mOtfMPPs[i]->setupRestriction();
2502     }
2503 
2504     for (uint32_t i = 0; i < mM2mMPPs.size(); i++) {
2505         // mAttr should be updated with updated feature_table
2506         mM2mMPPs[i]->updateAttr();
2507         mM2mMPPs[i]->setupRestriction();
2508     }
2509 }
2510 
getFeatureTableSize() const2511 uint32_t ExynosResourceManager::getFeatureTableSize() const
2512 {
2513     return sizeof(feature_table)/sizeof(feature_support_t);
2514 }
2515 
hasHDR10PlusMPP()2516 bool ExynosResourceManager::hasHDR10PlusMPP() {
2517 
2518     for (uint32_t i = 0; i < mOtfMPPs.size(); i++) {
2519         if (mOtfMPPs[i] == NULL) continue;
2520         if (mOtfMPPs[i]->mAttr & MPP_ATTR_HDR10PLUS)
2521             return true;
2522     }
2523     for (uint32_t i = 0; i < mM2mMPPs.size(); i++) {
2524         if (mM2mMPPs[i] == NULL) continue;
2525         if (mM2mMPPs[i]->mAttr & MPP_ATTR_HDR10PLUS)
2526             return true;
2527     }
2528 
2529     return false;
2530 }
2531 
getAssignedCapacity(uint32_t physicalType)2532 float ExynosResourceManager::getAssignedCapacity(uint32_t physicalType)
2533 {
2534     float totalCapacity = 0;
2535 
2536     for (size_t i = 0; i < mM2mMPPs.size(); i++) {
2537         if (mM2mMPPs[i]->mPhysicalType == physicalType)
2538             totalCapacity += mM2mMPPs[i]->getAssignedCapacity();
2539     }
2540     return totalCapacity;
2541 }
2542 
getM2MCapa(uint32_t physicalType)2543 float ExynosResourceManager::getM2MCapa(uint32_t physicalType)
2544 {
2545     float ret = 0;
2546     for (size_t i = 0; i < mM2mMPPs.size(); i++) {
2547         if (mM2mMPPs[i]->mPhysicalType == physicalType)
2548             return mM2mMPPs[i]->mCapacity;
2549     }
2550 
2551     return ret;
2552 }
2553 
dump(String8 & result) const2554 void ExynosResourceManager::dump(String8 &result) const {
2555     result.appendFormat("Resource Manager:\n");
2556 
2557     result.appendFormat("[RGB Restrictions]\n");
2558     dump(RESTRICTION_RGB, result);
2559 
2560     result.appendFormat("[YUV Restrictions]\n");
2561     dump(RESTRICTION_YUV, result);
2562 }
2563 
dump(const restriction_classification_t classification,String8 & result) const2564 void ExynosResourceManager::dump(const restriction_classification_t classification,
2565                                  String8 &result) const {
2566     const auto &restrictions = mSizeRestrictions[classification];
2567     const auto &restrictionCnt = mSizeRestrictionCnt[classification];
2568 
2569     for (int i = 0; i < restrictionCnt; ++i) {
2570         result.appendFormat("HW-Node %u-%u:\n", restrictions[i].key.hwType,
2571                             restrictions[i].key.nodeType);
2572         if (i > 0 && restrictions[i].sizeRestriction == restrictions[i - 1].sizeRestriction) {
2573             result.append("Same as above\n");
2574         } else {
2575             ::dump(restrictions[i].sizeRestriction, result);
2576         }
2577         result.appendFormat("\n");
2578     }
2579 }
2580 
setM2MCapa(uint32_t physicalType,uint32_t capa)2581 void ExynosResourceManager::setM2MCapa(uint32_t physicalType, uint32_t capa)
2582 {
2583     for (size_t i = 0; i < mM2mMPPs.size(); i++) {
2584         if (mM2mMPPs[i]->mPhysicalType == physicalType)
2585             mM2mMPPs[i]->mCapacity = capa;
2586     }
2587 }
2588