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