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