• 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.string());
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.string());
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.string());
447         result.clear();
448         display->mExynosCompositionInfo.dump(result);
449         HDEBUGLOGD(eDebugResourceManager, "%s", result.string());
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.string());
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.string(), 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.string());
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.string(), 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.string());
541                 m2mMPP->reserveMPP();
542             }
543         } else {
544             HDEBUGLOGD(eDebugResourceManager, "%s setting priority is ok", m2mMPP->mName.string());
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.string());
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.string(), 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.string(), 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.string(), 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.string(), 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.string(), ret);
826             return ret;
827         }
828         HDEBUGLOGD(eDebugResourceAssigning, "\t\t[%d] layer: %s MPP is assigned", layer_index,
829                    otfMPP->mName.string());
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.string(), 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.string());
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.string(), -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.string(), 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.string());
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         std::find_if(mOtfMPPs.begin(), mOtfMPPs.end(),
1210                      [&dst_scale_img, &dst_img, &otfMpp, &otfMppRatio](auto m) {
1211                          auto ratio = m->getMaxUpscale(dst_scale_img, dst_img);
1212                          if (ratio > 1) {
1213                              otfMpp = m;
1214                              otfMppRatio = ratio;
1215                              return true;
1216                          }
1217                          return false;
1218                      });
1219         const auto reqRatio = max(float(dst_img.w) / float(srcWidth * otfMppRatio),
1220                                   float(dst_img.h) / float(srcHeight * otfMppRatio));
1221         std::find_if(mM2mMPPs.begin(), mM2mMPPs.end(),
1222                      [&src_img, &dst_scale_img, reqRatio, &m2mMpp, &m2mMppRatio](auto m) {
1223                          float ratio = float(m->getMaxUpscale(src_img, dst_scale_img));
1224                          if (ratio > reqRatio) {
1225                              m2mMpp = m;
1226                              m2mMppRatio = ratio;
1227                              return true;
1228                          }
1229                          return false;
1230                      });
1231     } else {
1232         std::find_if(mM2mMPPs.begin(), mM2mMPPs.end(),
1233                      [&src_img, &dst_scale_img, display, &m2mMpp, &m2mMppRatio](auto m) {
1234                          auto ratio = m->getMaxDownscale(*display, src_img, dst_scale_img);
1235                          if (ratio > 1) {
1236                              m2mMpp = m;
1237                              m2mMppRatio = ratio;
1238                              return true;
1239                          }
1240                          return false;
1241                      });
1242 
1243         const float otfSrcWidth = float(srcWidth / m2mMppRatio);
1244         const float scaleRatio_H = otfSrcWidth / float(dst_img.w);
1245         const float otfSrcHeight = float(srcHeight / m2mMppRatio);
1246         const float scaleRatio_V = otfSrcHeight / float(dst_img.h);
1247         const float displayRatio_V = float(dst_img.h) / float(display->mYres);
1248         const float resolution = otfSrcWidth * otfSrcHeight * display->getBtsRefreshRate() / 1000;
1249 
1250         std::find_if(mOtfMPPs.begin(), mOtfMPPs.end(),
1251                      [&dst_scale_img, &dst_img, resolution, scaleRatio_H, scaleRatio_V,
1252                       displayRatio_V, &otfMpp, &otfMppRatio](auto m) {
1253                          auto ratio = m->getDownscaleRestriction(dst_scale_img, dst_img);
1254 
1255                          if (ratio >= scaleRatio_H && ratio >= scaleRatio_V &&
1256                              m->checkDownscaleCap(resolution, displayRatio_V)) {
1257                              otfMpp = m;
1258                              otfMppRatio = ratio;
1259                              return true;
1260                          }
1261                          return false;
1262                      });
1263     }
1264 
1265     if (!otfMpp && !m2mMpp) {
1266         HDEBUGLOGD(eDebugResourceManager,
1267                    "Cannot find available MPP for scaling src %d x %d, dst %d x %d", src_img.w,
1268                    src_img.h, dst_img.w, dst_img.h);
1269         return;
1270     }
1271 
1272     dst_scale_img.x = 0;
1273     dst_scale_img.y = 0;
1274     dst_scale_img.w = scaleDown ? dst_img.w : srcWidth;
1275     dst_scale_img.h = scaleDown ? dst_img.h : srcHeight;
1276 
1277     HDEBUGLOGD(eDebugResourceManager,
1278                "scaling w: %d, h: %d, ratio = otfType %d - %d, m2mType %d - %d", dst_scale_img.w,
1279                dst_scale_img.h, otfMpp ? otfMpp->mLogicalType : -1, otfMppRatio,
1280                m2mMpp ? m2mMpp->mLogicalType : -1, m2mMppRatio);
1281     if (scaleUp) {
1282         if (dst_scale_img.w * otfMppRatio < dst_img.w) {
1283             dst_scale_img.w = uint32_t(ceilf(float(dst_img.w) / float(otfMppRatio)));
1284         }
1285         if (dst_scale_img.h * otfMppRatio < dst_img.h) {
1286             dst_scale_img.h = uint32_t(ceilf(float(dst_img.h) / float(otfMppRatio)));
1287         }
1288     } else {
1289         if (dst_scale_img.w * m2mMppRatio < srcWidth) {
1290             dst_scale_img.w = uint32_t(ceilf(float(srcWidth) / float(m2mMppRatio)));
1291         }
1292         if (dst_scale_img.h * m2mMppRatio < srcHeight) {
1293             dst_scale_img.h = uint32_t(ceilf(float(srcHeight) / float(m2mMppRatio)));
1294         }
1295     }
1296     HDEBUGLOGD(eDebugResourceAssigning,
1297                "\tsrc[%d, %d, %d,%d], dst[%d, %d, %d,%d], mid[%d, %d, %d, %d]", src_img.x,
1298                src_img.y, src_img.w, src_img.h, dst_img.x, dst_img.y, dst_img.w, dst_img.h,
1299                dst_scale_img.x, dst_scale_img.y, dst_scale_img.w, dst_scale_img.h);
1300 
1301     if (isFormatSBWC(dst_scale_img.format)) {
1302         image_lists.emplace_back(getAlignedImage(dst_scale_img, m2mMpp, otfMpp));
1303         /*
1304          * SBWC format could not be supported in specific dst size
1305          * Add uncompressed YUV format to cover this size
1306          */
1307         dst_scale_img.format = DEFAULT_MPP_DST_UNCOMP_YUV_FORMAT;
1308     }
1309 
1310     image_lists.emplace_back(getAlignedImage(dst_scale_img, m2mMpp, otfMpp));
1311 }
1312 
getCandidateM2mMPPOutImages(ExynosDisplay * display,ExynosLayer * layer,std::vector<exynos_image> & image_lists)1313 int32_t ExynosResourceManager::getCandidateM2mMPPOutImages(ExynosDisplay *display,
1314         ExynosLayer *layer, std::vector<exynos_image> &image_lists)
1315 {
1316     exynos_image src_img;
1317     exynos_image dst_img;
1318     layer->setSrcExynosImage(&src_img);
1319     layer->setDstExynosImage(&dst_img);
1320     /* Position is (0, 0) */
1321     dst_img.x = 0;
1322     dst_img.y = 0;
1323 
1324     /* Check original source format first */
1325     dst_img.format = src_img.format;
1326     dst_img.dataSpace = src_img.dataSpace;
1327 
1328     /* Copy origin source HDR metadata */
1329     dst_img.metaParcel = src_img.metaParcel;
1330 
1331     getCandidateScalingM2mMPPOutImages(display, src_img, dst_img, image_lists);
1332 
1333     if (isFormatYUV(src_img.format) && !hasHdrInfo(src_img)) {
1334         dst_img.format = DEFAULT_MPP_DST_YUV_FORMAT;
1335     }
1336 
1337     ExynosExternalDisplay *external_display =
1338         (ExynosExternalDisplay*)mDevice->getDisplay(getDisplayId(HWC_DISPLAY_EXTERNAL, 0));
1339 
1340     /* For HDR through MSC or G2D case but dataspace is not changed */
1341     if (hasHdrInfo(src_img)) {
1342         if (isFormatYUV(src_img.format))
1343             dst_img.format = HAL_PIXEL_FORMAT_YCBCR_P010;
1344         else
1345             dst_img.format = HAL_PIXEL_FORMAT_RGBA_1010102;
1346         dst_img.dataSpace = src_img.dataSpace;
1347 
1348         /*
1349          * Align dst size
1350          * HDR10Plus should able to be processed by VGRFS
1351          * HDR on primary display should be processed by VGRFS
1352          * when external display is connected
1353          * because G2D is used by external display
1354          */
1355         if (hasHdr10Plus(dst_img) ||
1356             ((external_display != NULL) && (external_display->mPlugState) &&
1357              (display->mType == HWC_DISPLAY_PRIMARY))) {
1358             ExynosMPP *otfMppForHDRPlus = nullptr;
1359             auto mpp_it = std::find_if(mOtfMPPs.begin(), mOtfMPPs.end(),
1360                     [](auto m) {
1361                     return (m->mAttr & MPP_ATTR_HDR10PLUS);
1362                     });
1363             otfMppForHDRPlus = mpp_it == mOtfMPPs.end() ? nullptr : *mpp_it;
1364             uint32_t srcCropWidthAlign = 1;
1365             uint32_t srcCropHeightAlign = 1;
1366             if (otfMppForHDRPlus) {
1367                 srcCropWidthAlign = otfMppForHDRPlus->getSrcCropWidthAlign(dst_img);
1368                 srcCropHeightAlign = otfMppForHDRPlus->getSrcCropHeightAlign(dst_img);
1369             }
1370             dst_img.w = pixel_align(dst_img.w, srcCropWidthAlign);
1371             dst_img.h = pixel_align(dst_img.h, srcCropHeightAlign);
1372         }
1373     }
1374 
1375     image_lists.push_back(dst_img);
1376     if (isFormatSBWC(dst_img.format)) {
1377         /*
1378          * SBWC format could not be supported in specific dst size
1379          * Add uncompressed YUV format to cover this size
1380          */
1381         dst_img.format = DEFAULT_MPP_DST_UNCOMP_YUV_FORMAT;
1382         image_lists.push_back(dst_img);
1383     }
1384 
1385     /* For G2D HDR case */
1386     if (hasHdrInfo(src_img)) {
1387         bool isExternalPlugged = false;
1388         isHdrExternal = false;
1389 
1390         if (external_display != NULL) {
1391             if (external_display->mPlugState) isExternalPlugged = true;
1392             if (isExternalPlugged && (external_display->mExternalHdrSupported == true))
1393                 isHdrExternal = true;
1394         }
1395 
1396         if (isHdrExternal && (display->mType == HWC_DISPLAY_EXTERNAL)) {
1397             dst_img.format = HAL_PIXEL_FORMAT_RGBA_1010102;
1398             dst_img.dataSpace = src_img.dataSpace;
1399         } else {
1400             uint32_t dataspace = HAL_DATASPACE_UNKNOWN;
1401             if (display->mColorMode == HAL_COLOR_MODE_NATIVE) {
1402                 dataspace = HAL_DATASPACE_DCI_P3;
1403                 dataspace &= ~HAL_DATASPACE_TRANSFER_MASK;
1404                 dataspace |= HAL_DATASPACE_TRANSFER_GAMMA2_2;
1405                 dataspace &= ~HAL_DATASPACE_RANGE_MASK;
1406                 dataspace |= HAL_DATASPACE_RANGE_LIMITED;
1407             } else {
1408                 dataspace = colorModeToDataspace(display->mColorMode);
1409             }
1410             dst_img.format = HAL_PIXEL_FORMAT_RGBX_8888;
1411             dst_img.dataSpace = (android_dataspace)dataspace;
1412         }
1413 
1414         /*
1415          * This image is not pushed for primary display
1416          * if external display is connected
1417          * because G2D is used only for HDR on exernal display
1418          */
1419         if (!(isExternalPlugged && (display->mType == HWC_DISPLAY_PRIMARY))) {
1420             image_lists.push_back(dst_img);
1421         }
1422     }
1423 
1424     if (isFormatYUV(src_img.format) && !hasHdrInfo(src_img)) {
1425         /* Check RGB format */
1426         dst_img.format = DEFAULT_MPP_DST_FORMAT;
1427         if (display->mColorMode == HAL_COLOR_MODE_NATIVE) {
1428             /* Bypass dataSpace */
1429             dst_img.dataSpace = src_img.dataSpace;
1430         } else {
1431             /* Covert data space */
1432             dst_img.dataSpace = colorModeToDataspace(display->mColorMode);
1433         }
1434         image_lists.push_back(dst_img);
1435     }
1436 
1437     /*
1438      * image_lists[] would be src of otfMPP.
1439      * Layer color transform should be addressed
1440      * with dataspace conversion.
1441      * It should be addressed by m2mMPP if m2mMPP converts dataspace.
1442      * In other cases, m2mMPP ignores color transform setting and
1443      * otfMPP addresses layer color transform if it is necessary.
1444      */
1445     for (auto &image: image_lists) {
1446         if (image.dataSpace == src_img.dataSpace)
1447             image.needColorTransform = src_img.needColorTransform;
1448         else
1449             image.needColorTransform = false;
1450 
1451     }
1452 
1453     return static_cast<int32_t>(image_lists.size());
1454 }
1455 
assignLayer(ExynosDisplay * display,ExynosLayer * layer,uint32_t layer_index,exynos_image & m2m_out_img,ExynosMPP ** m2mMPP,ExynosMPP ** otfMPP,uint32_t & overlayInfo)1456 int32_t ExynosResourceManager::assignLayer(ExynosDisplay *display, ExynosLayer *layer, uint32_t layer_index,
1457         exynos_image &m2m_out_img, ExynosMPP **m2mMPP, ExynosMPP **otfMPP, uint32_t &overlayInfo)
1458 {
1459     int32_t ret = NO_ERROR;
1460     uint32_t validateFlag = 0;
1461 
1462     exynos_image src_img;
1463     exynos_image dst_img;
1464     layer->setSrcExynosImage(&src_img);
1465     layer->setDstExynosImage(&dst_img);
1466     layer->setExynosImage(src_img, dst_img);
1467     layer->setExynosMidImage(dst_img);
1468 
1469     validateFlag = validateLayer(layer_index, display, layer);
1470     if ((display->mUseDpu) &&
1471         (display->mWindowNumUsed >= display->mMaxWindowNum))
1472         validateFlag |= eInsufficientWindow;
1473 
1474     HDEBUGLOGD(eDebugResourceManager, "\t[%d] layer: validateFlag(0x%8x), supportedMPPFlag(0x%8x)",
1475             layer_index, validateFlag, layer->mSupportedMPPFlag);
1476 
1477     if (hwcCheckDebugMessages(eDebugResourceAssigning)) {
1478         layer->printLayer();
1479     }
1480 
1481     if ((validateFlag == NO_ERROR) || (validateFlag == eInsufficientWindow) ||
1482         (validateFlag == eDimLayer)) {
1483         bool isAssignableFlag = false;
1484         uint64_t isSupported = 0;
1485         /* 1. Find available otfMPP */
1486         if (validateFlag != eInsufficientWindow) {
1487             otfMppReordering(display, mOtfMPPs, src_img, dst_img);
1488 
1489             for (uint32_t j = 0; j < mOtfMPPs.size(); j++) {
1490                 if ((layer->mSupportedMPPFlag & mOtfMPPs[j]->mLogicalType) != 0)
1491                     isAssignableFlag = isAssignable(mOtfMPPs[j], display, src_img, dst_img, layer);
1492 
1493                 HDEBUGLOGD(eDebugResourceAssigning,
1494                            "\t\t check %s: flag (%d) supportedBit(%d), isAssignable(%d)",
1495                            mOtfMPPs[j]->mName.string(), layer->mSupportedMPPFlag,
1496                            (layer->mSupportedMPPFlag & mOtfMPPs[j]->mLogicalType),
1497                            isAssignableFlag);
1498 
1499                 if ((layer->mSupportedMPPFlag & mOtfMPPs[j]->mLogicalType) && (isAssignableFlag)) {
1500                     isSupported = mOtfMPPs[j]->isSupported(*display, src_img, dst_img);
1501                     HDEBUGLOGD(eDebugResourceAssigning, "\t\t\t isSupported(%" PRIx64 ")",
1502                                -isSupported);
1503                     if (isSupported == NO_ERROR) {
1504                         *otfMPP = mOtfMPPs[j];
1505                         return HWC2_COMPOSITION_DEVICE;
1506                     }
1507                 }
1508             }
1509         }
1510 
1511         /* 2. Find available m2mMPP */
1512         for (uint32_t j = 0; j < mM2mMPPs.size(); j++) {
1513             if ((display->mUseDpu == true) &&
1514                 (mM2mMPPs[j]->mLogicalType == MPP_LOGICAL_G2D_COMBO))
1515                 continue;
1516             if ((display->mUseDpu == false) &&
1517                 (mM2mMPPs[j]->mLogicalType == MPP_LOGICAL_G2D_RGB))
1518                 continue;
1519 
1520             /* Only G2D can be assigned if layer is supported by G2D
1521              * when window is not sufficient
1522              */
1523             if ((validateFlag == eInsufficientWindow) &&
1524                 (mM2mMPPs[j]->mLogicalType != MPP_LOGICAL_G2D_RGB) &&
1525                 (mM2mMPPs[j]->mLogicalType != MPP_LOGICAL_G2D_COMBO)) {
1526                 HDEBUGLOGD(eDebugResourceAssigning,
1527                            "\t\tInsufficient window but exynosComposition is not assigned");
1528                 continue;
1529             }
1530 
1531             bool isAssignableState = mM2mMPPs[j]->isAssignableState(display, src_img, dst_img);
1532 
1533             HDEBUGLOGD(eDebugResourceAssigning,
1534                        "\t\t check %s: supportedBit(%d), isAssignableState(%d)",
1535                        mM2mMPPs[j]->mName.string(),
1536                        (layer->mSupportedMPPFlag & mM2mMPPs[j]->mLogicalType), isAssignableState);
1537 
1538             float totalUsedCapa = ExynosResourceManager::getResourceUsedCapa(*mM2mMPPs[j]);
1539             if (isAssignableState) {
1540                 if ((mM2mMPPs[j]->mLogicalType != MPP_LOGICAL_G2D_RGB) &&
1541                     (mM2mMPPs[j]->mLogicalType != MPP_LOGICAL_G2D_COMBO)) {
1542                     exynos_image otf_dst_img = dst_img;
1543 
1544                     otf_dst_img.format = DEFAULT_MPP_DST_FORMAT;
1545 
1546                     std::vector<exynos_image> image_lists;
1547                     if ((ret = getCandidateM2mMPPOutImages(display, layer, image_lists)) < 0)
1548                     {
1549                         HWC_LOGE(display, "Fail getCandidateM2mMPPOutImages (%d)", ret);
1550                         return ret;
1551                     }
1552                     HDEBUGLOGD(eDebugResourceAssigning, "candidate M2mMPPOutImage num: %zu",
1553                                image_lists.size());
1554                     for (auto &otf_src_img : image_lists) {
1555                         dumpExynosImage(eDebugResourceAssigning, otf_src_img);
1556                         exynos_image m2m_src_img = src_img;
1557                         /* transform is already handled by m2mMPP */
1558                         if (CC_UNLIKELY(otf_src_img.transform != 0 || otf_dst_img.transform != 0)) {
1559                             ALOGE("%s:: transform should be handled by m2mMPP. otf_src_img "
1560                                   "transform %d, otf_dst_img transform %d",
1561                                   __func__, otf_src_img.transform, otf_dst_img.transform);
1562                             otf_src_img.transform = 0;
1563                             otf_dst_img.transform = 0;
1564                         }
1565 
1566                         /*
1567                          * This is the case that layer color transform should be
1568                          * addressed by otfMPP not m2mMPP
1569                          */
1570                         if (otf_src_img.needColorTransform)
1571                             m2m_src_img.needColorTransform = false;
1572 
1573                         if (((isSupported = mM2mMPPs[j]->isSupported(*display, m2m_src_img,
1574                                                                      otf_src_img)) != NO_ERROR) ||
1575                             ((isAssignableFlag =
1576                                       mM2mMPPs[j]->hasEnoughCapa(display, m2m_src_img, otf_src_img,
1577                                                                  totalUsedCapa)) == false)) {
1578                             HDEBUGLOGD(eDebugResourceAssigning,
1579                                        "\t\t\t check %s: supportedBit(0x%" PRIx64
1580                                        "), hasEnoughCapa(%d)",
1581                                        mM2mMPPs[j]->mName.string(), -isSupported, isAssignableFlag);
1582                             continue;
1583                         }
1584 
1585                         otfMppReordering(display, mOtfMPPs, otf_src_img, otf_dst_img);
1586 
1587                         /* 3. Find available OtfMPP for output of m2mMPP */
1588                         for (uint32_t k = 0; k < mOtfMPPs.size(); k++) {
1589                             isSupported = mOtfMPPs[k]->isSupported(*display, otf_src_img, otf_dst_img);
1590                             isAssignableFlag = false;
1591                             if (isSupported == NO_ERROR) {
1592                                 /* to prevent HW resource execeeded */
1593                                 ExynosCompositionInfo dpuSrcInfo;
1594                                 dpuSrcInfo.mSrcImg = otf_src_img;
1595                                 dpuSrcInfo.mDstImg = otf_dst_img;
1596                                 HDEBUGLOGD(eDebugTDM,
1597                                            "%s Composition target calculation start (candidates)",
1598                                            __func__);
1599                                 calculateHWResourceAmount(display, &dpuSrcInfo);
1600 
1601                                 isAssignableFlag = isAssignable(mOtfMPPs[k], display, otf_src_img,
1602                                                                 otf_dst_img, &dpuSrcInfo);
1603                             }
1604 
1605                             HDEBUGLOGD(eDebugResourceAssigning,
1606                                        "\t\t\t check %s: supportedBit(0x%" PRIx64
1607                                        "), isAssignable(%d)",
1608                                        mOtfMPPs[k]->mName.string(), -isSupported, isAssignableFlag);
1609                             if ((isSupported == NO_ERROR) && isAssignableFlag) {
1610                                 *m2mMPP = mM2mMPPs[j];
1611                                 *otfMPP = mOtfMPPs[k];
1612                                 m2m_out_img = otf_src_img;
1613                                 return HWC2_COMPOSITION_DEVICE;
1614                             }
1615                         }
1616                     }
1617                 } else {
1618                     if ((layer->mSupportedMPPFlag & mM2mMPPs[j]->mLogicalType) &&
1619                         ((isAssignableFlag = mM2mMPPs[j]->hasEnoughCapa(display, src_img, dst_img,
1620                                                                         totalUsedCapa) == true))) {
1621                         *m2mMPP = mM2mMPPs[j];
1622                         return HWC2_COMPOSITION_EXYNOS;
1623                     } else {
1624                         HDEBUGLOGD(eDebugResourceManager,
1625                                    "\t\t\t check %s: layer's mSupportedMPPFlag(0x%8x), "
1626                                    "hasEnoughCapa(%d)",
1627                                    mM2mMPPs[j]->mName.string(), layer->mSupportedMPPFlag,
1628                                    isAssignableFlag);
1629                     }
1630                 }
1631             }
1632         }
1633     }
1634     /* Fail to assign resource */
1635     if (validateFlag != NO_ERROR)
1636         overlayInfo = validateFlag;
1637     else
1638         overlayInfo = eMPPUnsupported;
1639     return HWC2_COMPOSITION_CLIENT;
1640 }
1641 
assignLayers(ExynosDisplay * display,uint32_t priority)1642 int32_t ExynosResourceManager::assignLayers(ExynosDisplay * display, uint32_t priority)
1643 {
1644     HDEBUGLOGD(eDebugResourceAssigning, "%s:: display(%d), priority(%d) +++++", __func__,
1645                display->mType, priority);
1646 
1647     int32_t ret = NO_ERROR;
1648     bool needReAssign = false;
1649     for (uint32_t i = 0; i < display->mLayers.size(); i++) {
1650         ExynosLayer *layer = display->mLayers[i];
1651         ExynosMPP *m2mMPP = NULL;
1652         ExynosMPP *otfMPP = NULL;
1653         exynos_image m2m_out_img;
1654         uint32_t validateFlag = 0;
1655         int32_t compositionType = 0;
1656 
1657         if ((layer->mValidateCompositionType == HWC2_COMPOSITION_CLIENT) ||
1658             (layer->mValidateCompositionType == HWC2_COMPOSITION_EXYNOS))
1659             continue;
1660         if (layer->mOverlayPriority != priority)
1661             continue;
1662 
1663         exynos_image src_img;
1664         exynos_image dst_img;
1665         layer->setSrcExynosImage(&src_img);
1666         layer->setDstExynosImage(&dst_img);
1667         layer->setExynosImage(src_img, dst_img);
1668         layer->setExynosMidImage(dst_img);
1669 
1670         // TODO: call validate function for RCD layer
1671         if (layer->mCompositionType == HWC2_COMPOSITION_DISPLAY_DECORATION &&
1672             validateRCDLayer(*display, *layer, i, src_img, dst_img) == NO_ERROR) {
1673             layer->mValidateCompositionType = HWC2_COMPOSITION_DISPLAY_DECORATION;
1674             continue;
1675         }
1676 
1677         compositionType = assignLayer(display, layer, i, m2m_out_img, &m2mMPP, &otfMPP, validateFlag);
1678         if (compositionType == HWC2_COMPOSITION_DEVICE) {
1679             if (otfMPP != NULL) {
1680                 if ((ret = otfMPP->assignMPP(display, layer)) != NO_ERROR)
1681                 {
1682                     ALOGE("%s:: %s MPP assignMPP() error (%d)",
1683                             __func__, otfMPP->mName.string(), ret);
1684                     return ret;
1685                 }
1686                 HDEBUGLOGD(eDebugResourceAssigning, "\t\t[%d] layer: %s MPP is assigned", i,
1687                            otfMPP->mName.string());
1688             }
1689             if (m2mMPP != NULL) {
1690                 if ((ret = m2mMPP->assignMPP(display, layer)) != NO_ERROR)
1691                 {
1692                     ALOGE("%s:: %s MPP assignMPP() error (%d)",
1693                             __func__, m2mMPP->mName.string(), ret);
1694                     return ret;
1695                 }
1696                 layer->setExynosMidImage(m2m_out_img);
1697                 HDEBUGLOGD(eDebugResourceAssigning, "\t\t[%d] layer: %s MPP is assigned", i,
1698                            m2mMPP->mName.string());
1699             }
1700             layer->mValidateCompositionType = compositionType;
1701             display->mWindowNumUsed++;
1702             HDEBUGLOGD(eDebugResourceAssigning, "\t\t[%d] layer: mWindowNumUsed(%d)", i,
1703                        display->mWindowNumUsed);
1704         } else if (compositionType == HWC2_COMPOSITION_EXYNOS) {
1705             float totalUsedCapacity = 0;
1706             if (m2mMPP != NULL) {
1707                 if ((ret = m2mMPP->assignMPP(display, layer)) != NO_ERROR)
1708                 {
1709                     ALOGE("%s:: %s MPP assignMPP() error (%d)",
1710                             __func__, m2mMPP->mName.string(), ret);
1711                     return ret;
1712                 }
1713                 totalUsedCapacity = getResourceUsedCapa(*m2mMPP);
1714                 HDEBUGLOGD(eDebugResourceAssigning, "\t\t[%d] layer: %s MPP is assigned", i,
1715                            m2mMPP->mName.string());
1716             }
1717             layer->mValidateCompositionType = compositionType;
1718 
1719             HDEBUGLOGD(eDebugResourceAssigning, "\t\t[%d] layer: exynosComposition", i);
1720             /* G2D composition */
1721             if (((ret = display->addExynosCompositionLayer(i, totalUsedCapacity)) ==
1722                  EXYNOS_ERROR_CHANGED) ||
1723                 (ret < 0))
1724                 return ret;
1725             else {
1726                 /*
1727                  * If high fps layer should be composited by GLES then
1728                  * disable handling low fps feature and reassign resources
1729                  */
1730                 if ((display->mLowFpsLayerInfo.mHasLowFpsLayer == true) &&
1731                     (display->mClientCompositionInfo.mHasCompositionLayer == true) &&
1732                     ((display->mClientCompositionInfo.mFirstIndex < display->mLowFpsLayerInfo.mFirstIndex) ||
1733                      (display->mClientCompositionInfo.mLastIndex > display->mLowFpsLayerInfo.mLastIndex))) {
1734                     needReAssign = true;
1735                     break;
1736                 }
1737             }
1738         } else {
1739             /*
1740              * If high fps layer should be composited by GLES then
1741              * disable handling low fps feature and reassign resources
1742             */
1743             if ((display->mLowFpsLayerInfo.mHasLowFpsLayer == true) &&
1744                 (((int32_t)i < display->mLowFpsLayerInfo.mFirstIndex) ||
1745                  (display->mLowFpsLayerInfo.mLastIndex < (int32_t)i))) {
1746                 needReAssign = true;
1747                 break;
1748             }
1749 
1750             /* Fail to assign resource, set HWC2_COMPOSITION_CLIENT */
1751             if (validateFlag != NO_ERROR)
1752                 layer->mOverlayInfo |= validateFlag;
1753             else
1754                 layer->mOverlayInfo |= eMPPUnsupported;
1755 
1756             layer->mValidateCompositionType = HWC2_COMPOSITION_CLIENT;
1757             if (((ret = display->addClientCompositionLayer(i)) == EXYNOS_ERROR_CHANGED) ||
1758                 (ret < 0))
1759                 return ret;
1760         }
1761     }
1762     if (needReAssign) {
1763         if ((display->mClientCompositionInfo.mHasCompositionLayer) &&
1764                 (display->mClientCompositionInfo.mOtfMPP != NULL))
1765             display->mClientCompositionInfo.mOtfMPP->resetAssignedState();
1766 
1767         if (display->mExynosCompositionInfo.mHasCompositionLayer) {
1768             if (display->mExynosCompositionInfo.mOtfMPP != NULL)
1769                 display->mExynosCompositionInfo.mOtfMPP->resetAssignedState();
1770             if (display->mExynosCompositionInfo.mM2mMPP != NULL)
1771                 display->mExynosCompositionInfo.mM2mMPP->resetAssignedState();
1772         }
1773 
1774         display->initializeValidateInfos();
1775         display->mLowFpsLayerInfo.initializeInfos();
1776         return EXYNOS_ERROR_CHANGED;
1777     }
1778     return ret;
1779 }
1780 
assignWindow(ExynosDisplay * display)1781 int32_t ExynosResourceManager::assignWindow(ExynosDisplay *display)
1782 {
1783     HDEBUGLOGD(eDebugResourceManager, "%s +++++", __func__);
1784     int ret = NO_ERROR;
1785     uint32_t windowIndex = 0;
1786 
1787     if (!display->mUseDpu)
1788         return ret;
1789 
1790     windowIndex = display->mBaseWindowIndex;
1791 
1792     for (uint32_t i = 0; i < display->mLayers.size(); i++) {
1793         ExynosLayer *layer = display->mLayers[i];
1794         HDEBUGLOGD(eDebugResourceAssigning, "\t[%d] layer type: %d", i,
1795                    layer->mValidateCompositionType);
1796 
1797         if (layer->mValidateCompositionType == HWC2_COMPOSITION_DEVICE) {
1798             layer->mWindowIndex = windowIndex;
1799             HDEBUGLOGD(eDebugResourceManager, "\t\t[%d] layer windowIndex: %d", i, windowIndex);
1800         } else if ((layer->mValidateCompositionType == HWC2_COMPOSITION_CLIENT) ||
1801                    (layer->mValidateCompositionType == HWC2_COMPOSITION_EXYNOS)) {
1802             ExynosCompositionInfo *compositionInfo;
1803             if (layer->mValidateCompositionType == HWC2_COMPOSITION_CLIENT)
1804                 compositionInfo = &display->mClientCompositionInfo;
1805             else
1806                 compositionInfo = &display->mExynosCompositionInfo;
1807 
1808             if ((compositionInfo->mHasCompositionLayer == false) ||
1809                 (compositionInfo->mFirstIndex < 0) ||
1810                 (compositionInfo->mLastIndex < 0)) {
1811                 HWC_LOGE(display, "%s:: Invalid %s CompositionInfo mHasCompositionLayer(%d), "
1812                         "mFirstIndex(%d), mLastIndex(%d) ",
1813                         __func__, compositionInfo->getTypeStr().string(),
1814                         compositionInfo->mHasCompositionLayer,
1815                         compositionInfo->mFirstIndex,
1816                         compositionInfo->mLastIndex);
1817                 continue;
1818             }
1819             if (i != (uint32_t)compositionInfo->mLastIndex)
1820                 continue;
1821             compositionInfo->mWindowIndex = windowIndex;
1822             HDEBUGLOGD(eDebugResourceManager, "\t\t[%d] %s Composition windowIndex: %d",
1823                     i, compositionInfo->getTypeStr().string(), windowIndex);
1824         } else if (layer->mValidateCompositionType == HWC2_COMPOSITION_DISPLAY_DECORATION) {
1825             layer->mWindowIndex = -1;
1826             continue;
1827         } else {
1828             HWC_LOGE(display, "%s:: Invalid layer compositionType layer(%d), compositionType(%d)",
1829                     __func__, i, layer->mValidateCompositionType);
1830             continue;
1831         }
1832         windowIndex++;
1833     }
1834     HDEBUGLOGD(eDebugResourceManager, "%s ------", __func__);
1835     return ret;
1836 }
1837 
1838 /**
1839  * @param * display
1840  * @return int
1841  */
updateSupportedMPPFlag(ExynosDisplay * display)1842 int32_t ExynosResourceManager::updateSupportedMPPFlag(ExynosDisplay * display)
1843 {
1844     int64_t ret = 0;
1845     HDEBUGLOGD(eDebugResourceAssigning, "%s++++++++++", __func__);
1846     for (uint32_t i = 0; i < display->mLayers.size(); i++) {
1847         ExynosLayer *layer = display->mLayers[i];
1848         HDEBUGLOGD(eDebugResourceAssigning, "[%d] layer ", i);
1849 
1850         if (layer->mGeometryChanged == 0)
1851             continue;
1852 
1853         exynos_image src_img;
1854         exynos_image dst_img;
1855         exynos_image dst_img_yuv;
1856         layer->setSrcExynosImage(&src_img);
1857         layer->setDstExynosImage(&dst_img);
1858         layer->setDstExynosImage(&dst_img_yuv);
1859         dst_img.format = DEFAULT_MPP_DST_FORMAT;
1860         dst_img_yuv.format = DEFAULT_MPP_DST_YUV_FORMAT;
1861         HDEBUGLOGD(eDebugResourceAssigning, "\tsrc_img");
1862         dumpExynosImage(eDebugResourceAssigning, src_img);
1863         HDEBUGLOGD(eDebugResourceAssigning, "\tdst_img");
1864         dumpExynosImage(eDebugResourceAssigning, dst_img);
1865 
1866         /* Initialize flags */
1867         layer->mSupportedMPPFlag = 0;
1868         layer->mCheckMPPFlag.clear();
1869 
1870         /* Check OtfMPPs */
1871         for (uint32_t j = 0; j < mOtfMPPs.size(); j++) {
1872             if ((ret = mOtfMPPs[j]->isSupported(*display, src_img, dst_img)) == NO_ERROR) {
1873                 layer->mSupportedMPPFlag |= mOtfMPPs[j]->mLogicalType;
1874                 HDEBUGLOGD(eDebugResourceAssigning, "\t%s: supported", mOtfMPPs[j]->mName.string());
1875             } else {
1876                 if (((-ret) == eMPPUnsupportedFormat) &&
1877                     ((ret = mOtfMPPs[j]->isSupported(*display, src_img, dst_img_yuv)) == NO_ERROR)) {
1878                     layer->mSupportedMPPFlag |= mOtfMPPs[j]->mLogicalType;
1879                     HDEBUGLOGD(eDebugResourceAssigning, "\t%s: supported with yuv dst",
1880                                mOtfMPPs[j]->mName.string());
1881                 }
1882             }
1883             if (ret < 0) {
1884                 HDEBUGLOGD(eDebugResourceAssigning, "\t%s: unsupported flag(0x%" PRIx64 ")",
1885                            mOtfMPPs[j]->mName.string(), -ret);
1886                 uint64_t checkFlag = 0x0;
1887                 if (layer->mCheckMPPFlag.find(mOtfMPPs[j]->mLogicalType) !=
1888                         layer->mCheckMPPFlag.end()) {
1889                     checkFlag = layer->mCheckMPPFlag.at(mOtfMPPs[j]->mLogicalType);
1890                 }
1891                 checkFlag |= (-ret);
1892                 layer->mCheckMPPFlag[mOtfMPPs[j]->mLogicalType] = checkFlag;
1893             }
1894         }
1895 
1896         /* Check M2mMPPs */
1897         for (uint32_t j = 0; j < mM2mMPPs.size(); j++) {
1898             if ((ret = mM2mMPPs[j]->isSupported(*display, src_img, dst_img)) == NO_ERROR) {
1899                 layer->mSupportedMPPFlag |= mM2mMPPs[j]->mLogicalType;
1900                 HDEBUGLOGD(eDebugResourceAssigning, "\t%s: supported", mM2mMPPs[j]->mName.string());
1901             } else {
1902                 if (((-ret) == eMPPUnsupportedFormat) &&
1903                     ((ret = mM2mMPPs[j]->isSupported(*display, src_img, dst_img_yuv)) == NO_ERROR)) {
1904                     layer->mSupportedMPPFlag |= mM2mMPPs[j]->mLogicalType;
1905                     HDEBUGLOGD(eDebugResourceAssigning, "\t%s: supported with yuv dst",
1906                                mM2mMPPs[j]->mName.string());
1907                 }
1908             }
1909             if (ret < 0) {
1910                 HDEBUGLOGD(eDebugResourceAssigning, "\t%s: unsupported flag(0x%" PRIx64 ")",
1911                            mM2mMPPs[j]->mName.string(), -ret);
1912                 uint64_t checkFlag = 0x0;
1913                 if (layer->mCheckMPPFlag.find(mM2mMPPs[j]->mLogicalType) !=
1914                         layer->mCheckMPPFlag.end()) {
1915                     checkFlag = layer->mCheckMPPFlag.at(mM2mMPPs[j]->mLogicalType);
1916                 }
1917                 checkFlag |= (-ret);
1918                 layer->mCheckMPPFlag[mM2mMPPs[j]->mLogicalType] = checkFlag;
1919             }
1920         }
1921         HDEBUGLOGD(eDebugResourceAssigning, "[%d] layer mSupportedMPPFlag(0x%8x)", i,
1922                    layer->mSupportedMPPFlag);
1923     }
1924     HDEBUGLOGD(eDebugResourceAssigning, "%s-------------", __func__);
1925 
1926     return NO_ERROR;
1927 }
1928 
resetResources()1929 int32_t ExynosResourceManager::resetResources()
1930 {
1931     HDEBUGLOGD(eDebugResourceManager, "%s+++++++++", __func__);
1932 
1933     for (uint32_t i = 0; i < mOtfMPPs.size(); i++) {
1934         mOtfMPPs[i]->resetMPP();
1935         if (hwcCheckDebugMessages(eDebugResourceManager)) {
1936             String8 dumpMPP;
1937             mOtfMPPs[i]->dump(dumpMPP);
1938             HDEBUGLOGD(eDebugResourceManager, "%s", dumpMPP.string());
1939         }
1940     }
1941     for (uint32_t i = 0; i < mM2mMPPs.size(); i++) {
1942         mM2mMPPs[i]->resetMPP();
1943         if (hwcCheckDebugMessages(eDebugResourceManager)) {
1944             String8 dumpMPP;
1945             mM2mMPPs[i]->dump(dumpMPP);
1946             HDEBUGLOGD(eDebugResourceManager, "%s", dumpMPP.string());
1947         }
1948     }
1949 
1950     HDEBUGLOGD(eDebugResourceManager, "%s-----------",  __func__);
1951     return NO_ERROR;
1952 }
1953 
preAssignResources()1954 int32_t ExynosResourceManager::preAssignResources()
1955 {
1956     HDEBUGLOGD(eDebugResourceManager, "%s+++++++++", __func__);
1957     uint32_t displayMode = mDevice->mDisplayMode;
1958 
1959     for (uint32_t i = 0; i < mOtfMPPs.size(); i++) {
1960         if (mOtfMPPs[i]->mEnable == false) {
1961             mOtfMPPs[i]->reserveMPP();
1962             continue;
1963         }
1964 
1965         if (mOtfMPPs[i]->mPreAssignDisplayList[displayMode] != 0) {
1966             HDEBUGLOGD(eDebugResourceAssigning, "\t%s check, dispMode(%d), 0x%8x",
1967                        mOtfMPPs[i]->mName.string(), displayMode,
1968                        mOtfMPPs[i]->mPreAssignDisplayList[displayMode]);
1969 
1970             ExynosDisplay *display = NULL;
1971             for (size_t j = 0; j < mDevice->mDisplays.size(); j++) {
1972                 display = mDevice->mDisplays[j];
1973                 if (display == nullptr)
1974                     continue;
1975                 int checkBit = mOtfMPPs[i]->mPreAssignDisplayList[displayMode] & display->getDisplayPreAssignBit();
1976                 HDEBUGLOGD(eDebugResourceAssigning, "\t\tdisplay index(%zu), checkBit(%d)", j,
1977                            checkBit);
1978                 if (checkBit) {
1979                     HDEBUGLOGD(eDebugResourceAssigning,
1980                                "\t\tdisplay index(%zu), displayId(%d), display(%p)", j,
1981                                display->mDisplayId, display);
1982                     if (display->mDisplayControl.forceReserveMPP ||
1983                         (display->mPlugState &&
1984                          ((display->mType != HWC_DISPLAY_PRIMARY) ||
1985                           (display->mPowerModeState.has_value() &&
1986                            (display->mPowerModeState.value() != HWC2_POWER_MODE_OFF))))) {
1987                         HDEBUGLOGD(eDebugResourceAssigning, "\t\treserve to display %d",
1988                                    display->mDisplayId);
1989                         mOtfMPPs[i]->reserveMPP(display->mDisplayId);
1990                         break;
1991                     }
1992                 }
1993             }
1994         }
1995     }
1996     for (uint32_t i = 0; i < mM2mMPPs.size(); i++) {
1997         if (mM2mMPPs[i]->mEnable == false) {
1998             mM2mMPPs[i]->reserveMPP();
1999             continue;
2000         }
2001 
2002         if (mResourceReserved & mM2mMPPs[i]->mLogicalType) {
2003             /* MSC can't be used for rendering */
2004             HDEBUGLOGD(eDebugResourceManager, "\t\tMPP_MSC reserve without display because preview is running");
2005             mM2mMPPs[i]->reserveMPP();
2006             continue;
2007         }
2008         HDEBUGLOGD(eDebugResourceAssigning, "\t%s check, 0x%8x", mM2mMPPs[i]->mName.string(),
2009                    mM2mMPPs[i]->mPreAssignDisplayList[displayMode]);
2010         if (mM2mMPPs[i]->mPreAssignDisplayList[displayMode] != 0) {
2011             ExynosDisplay *display = NULL;
2012             for (size_t j = 0; j < mDevice->mDisplays.size(); j++) {
2013                 display = mDevice->mDisplays[j];
2014                 int checkBit = mM2mMPPs[i]->mPreAssignDisplayList[displayMode] & display->getDisplayPreAssignBit();
2015                 HDEBUGLOGD(eDebugResourceAssigning, "\t\tdisplay index(%zu), checkBit(%d)", j,
2016                            checkBit);
2017                 if (checkBit) {
2018                     HDEBUGLOGD(eDebugResourceAssigning,
2019                                "\t\tdisplay index(%zu), displayId(%d), display(%p)", j,
2020                                display->mDisplayId, display);
2021                     if ((display != NULL) && (display->mPlugState == true)) {
2022                         HDEBUGLOGD(eDebugResourceAssigning, "\t\treserve to display %d",
2023                                    display->mDisplayId);
2024                         mM2mMPPs[i]->reserveMPP(display->mDisplayId);
2025                         break;
2026                     } else {
2027                         HDEBUGLOGD(eDebugResourceAssigning, "\t\treserve without display");
2028                         mM2mMPPs[i]->reserveMPP();
2029                     }
2030                 }
2031             }
2032         }
2033     }
2034     for (uint32_t i = 0; i < mOtfMPPs.size(); i++) {
2035         if (hwcCheckDebugMessages(eDebugResourceManager)) {
2036             String8 dumpMPP;
2037             mOtfMPPs[i]->dump(dumpMPP);
2038             HDEBUGLOGD(eDebugResourceManager, "%s", dumpMPP.string());
2039         }
2040     }
2041     for (uint32_t i = 0; i < mM2mMPPs.size(); i++) {
2042         if (hwcCheckDebugMessages(eDebugResourceManager)) {
2043             String8 dumpMPP;
2044             mM2mMPPs[i]->dump(dumpMPP);
2045             HDEBUGLOGD(eDebugResourceManager, "%s", dumpMPP.string());
2046         }
2047     }
2048     HDEBUGLOGD(eDebugResourceManager, "%s-----------",  __func__);
2049     return NO_ERROR;
2050 }
2051 
preAssignWindows(ExynosDisplay * display)2052 void ExynosResourceManager::preAssignWindows(ExynosDisplay *display) {
2053     ExynosPrimaryDisplayModule *primaryDisplay = NULL;
2054 
2055     if (display->mType == HWC_DISPLAY_PRIMARY) {
2056         primaryDisplay = (ExynosPrimaryDisplayModule *)display;
2057     } else {
2058         primaryDisplay = (ExynosPrimaryDisplayModule *)mDevice->getDisplay(
2059                 getDisplayId(HWC_DISPLAY_PRIMARY, 0));
2060     }
2061 
2062     primaryDisplay->usePreDefinedWindow(false);
2063 
2064     for (size_t i = 1; i < mDevice->mDisplays.size(); i++) {
2065         ExynosDisplay *disp = mDevice->mDisplays[i];
2066         if ((disp == NULL) || (display->mType != HWC_DISPLAY_EXTERNAL)) continue;
2067         if (disp->mPlugState == true) {
2068             primaryDisplay->usePreDefinedWindow(true);
2069         }
2070     }
2071 }
2072 
preProcessLayer(ExynosDisplay * display)2073 int32_t ExynosResourceManager::preProcessLayer(ExynosDisplay * display)
2074 {
2075     int32_t ret = 0;
2076     hasHdrLayer = false;
2077     hasDrmLayer = false;
2078 
2079     for (uint32_t i = 0; i < display->mLayers.size(); i++) {
2080         ExynosLayer *layer = display->mLayers[i];
2081         if ((ret = layer->doPreProcess()) < 0) {
2082             HWC_LOGE(display, "%s:: doPreProcess() error, display(%d), layer %d", __func__, display->mType, i);
2083             return ret;
2084         }
2085         /* mIsHdrLayer is known after preprocess */
2086         if (layer->mIsHdrLayer) hasHdrLayer = true;
2087         if ((layer->mLayerBuffer != NULL) && (getDrmMode(layer->mLayerBuffer) != NO_DRM))
2088             hasDrmLayer = true;
2089     }
2090 
2091     // Re-align layer priority for max overlay resources
2092     uint32_t mNumMaxPriorityLayers = 0;
2093     for (int i = (display->mLayers.size()-1); i >= 0; i--) {
2094         ExynosLayer *layer = display->mLayers[i];
2095         HDEBUGLOGD(eDebugResourceManager, "Priority align: i:%d, layer priority:%d, Max:%d, mNumMaxPriorityAllowed:%d", i,
2096                 layer->mOverlayPriority, mNumMaxPriorityLayers, display->mNumMaxPriorityAllowed);
2097         if (layer->mOverlayPriority == ePriorityMax) {
2098             if (mNumMaxPriorityLayers >= display->mNumMaxPriorityAllowed) {
2099                 layer->mOverlayPriority = ePriorityHigh;
2100             }
2101             mNumMaxPriorityLayers++;
2102         }
2103     }
2104 
2105     return NO_ERROR;
2106 }
2107 
getExynosMPP(uint32_t type)2108 ExynosMPP* ExynosResourceManager::getExynosMPP(uint32_t type)
2109 {
2110     for (uint32_t i = 0; i < mOtfMPPs.size(); i++) {
2111         if (mOtfMPPs[i]->mLogicalType == type)
2112             return mOtfMPPs[i];
2113     }
2114     for (uint32_t i = 0; i < mM2mMPPs.size(); i++) {
2115         if (mM2mMPPs[i]->mLogicalType == type)
2116             return mM2mMPPs[i];
2117     }
2118 
2119     return NULL;
2120 }
2121 
getExynosMPP(uint32_t physicalType,uint32_t physicalIndex)2122 ExynosMPP* ExynosResourceManager::getExynosMPP(uint32_t physicalType, uint32_t physicalIndex)
2123 {
2124     for (uint32_t i = 0; i < mOtfMPPs.size(); i++) {
2125         if ((mOtfMPPs[i]->mPhysicalType == physicalType) &&
2126             (mOtfMPPs[i]->mPhysicalIndex == physicalIndex))
2127             return mOtfMPPs[i];
2128     }
2129     for (uint32_t i = 0; i < mM2mMPPs.size(); i++) {
2130         if ((mM2mMPPs[i]->mPhysicalType == physicalType) &&
2131             (mM2mMPPs[i]->mPhysicalIndex == physicalIndex))
2132             return mM2mMPPs[i];
2133     }
2134 
2135     return NULL;
2136 }
2137 
updateResourceState()2138 int32_t ExynosResourceManager::updateResourceState()
2139 {
2140     for (uint32_t i = 0; i < mOtfMPPs.size(); i++) {
2141         if (mOtfMPPs[i]->mAssignedSources.size() == 0)
2142             mOtfMPPs[i]->requestHWStateChange(MPP_HW_STATE_IDLE);
2143         mOtfMPPs[i]->mPrevAssignedState = mOtfMPPs[i]->mAssignedState;
2144     }
2145     for (uint32_t i = 0; i < mM2mMPPs.size(); i++) {
2146         if (mM2mMPPs[i]->mAssignedSources.size() == 0)
2147             mM2mMPPs[i]->requestHWStateChange(MPP_HW_STATE_IDLE);
2148         mM2mMPPs[i]->mPrevAssignedState = mM2mMPPs[i]->mAssignedState;
2149     }
2150     return NO_ERROR;
2151 }
2152 
2153 /*
2154  * This function is called every frame.
2155  * This base function does nothing.
2156  * Module that supports setting frame rate should implement this function
2157  * in the module source code (hardware/samsung_slsi/graphics/exynos...).
2158  */
setFrameRateForPerformance(ExynosMPP & mpp,AcrylicPerformanceRequestFrame * frame)2159 void ExynosResourceManager::setFrameRateForPerformance(ExynosMPP &mpp,
2160         AcrylicPerformanceRequestFrame *frame)
2161 {
2162     int fps = ceil(msecsPerSec / mpp.mCapacity);
2163     HDEBUGLOGD(eDebugResourceAssigning, "%s setFrameRate %d",
2164             mpp.mName.string(), fps);
2165     frame->setFrameRate(fps);
2166 }
2167 
deliverPerformanceInfo()2168 int32_t ExynosResourceManager::deliverPerformanceInfo()
2169 {
2170     int ret = NO_ERROR;
2171     for (uint32_t mpp_physical_type = 0; mpp_physical_type < MPP_P_TYPE_MAX; mpp_physical_type++) {
2172         /* Only G2D gets performance info in current version */
2173         if (mpp_physical_type != MPP_G2D)
2174             continue;
2175         AcrylicPerformanceRequest request;
2176         uint32_t assignedInstanceNum = 0;
2177         uint32_t assignedInstanceIndex = 0;
2178         ExynosMPP *mpp = NULL;
2179         bool canSkipSetting = true;
2180 
2181         for (uint32_t i = 0; i < mM2mMPPs.size(); i++) {
2182             mpp = mM2mMPPs[i];
2183             if (mpp->mPhysicalType != mpp_physical_type)
2184                 continue;
2185             /* Performance setting can be skipped
2186              * if all of instance's mPrevAssignedState, mAssignedState
2187              * are MPP_ASSIGN_STATE_FREE
2188              */
2189             if ((mpp->mPrevAssignedState & MPP_ASSIGN_STATE_ASSIGNED) ||
2190                 (mpp->mAssignedState & MPP_ASSIGN_STATE_ASSIGNED))
2191             {
2192                 canSkipSetting = false;
2193             }
2194 
2195             if (mpp->canSkipProcessing())
2196                 continue;
2197 
2198             if ((mpp->mAssignedDisplay != NULL) &&
2199                 (mpp->mAssignedSources.size() > 0))
2200             {
2201                 assignedInstanceNum++;
2202             }
2203         }
2204         if ((canSkipSetting == true) && (assignedInstanceNum != 0)) {
2205             HWC_LOGE(NULL, "%s:: canSKip true but assignedInstanceNum(%d)",
2206                     __func__, assignedInstanceNum);
2207         }
2208         request.reset(assignedInstanceNum);
2209 
2210         if (canSkipSetting == true)
2211             continue;
2212 
2213         for (uint32_t i = 0; i < mM2mMPPs.size(); i++) {
2214             mpp = mM2mMPPs[i];
2215             if ((mpp->mPhysicalType == mpp_physical_type) &&
2216                 (mpp->mAssignedDisplay != NULL) &&
2217                 (mpp->mAssignedSources.size() > 0))
2218             {
2219                 if (mpp->canSkipProcessing())
2220                     continue;
2221                 if (assignedInstanceIndex >= assignedInstanceNum) {
2222                     HWC_LOGE(NULL,"assignedInstanceIndex error (%d, %d)", assignedInstanceIndex, assignedInstanceNum);
2223                     break;
2224                 }
2225                 AcrylicPerformanceRequestFrame *frame = request.getFrame(assignedInstanceIndex);
2226                 if(frame->reset(mpp->mAssignedSources.size()) == false) {
2227                     HWC_LOGE(NULL,"%d frame reset fail (%zu)", assignedInstanceIndex, mpp->mAssignedSources.size());
2228                     break;
2229                 }
2230                 setFrameRateForPerformance(*mpp, frame);
2231 
2232                 for (uint32_t j = 0; j < mpp->mAssignedSources.size(); j++) {
2233                     ExynosMPPSource* mppSource = mpp->mAssignedSources[j];
2234                     frame->setSourceDimension(j,
2235                             mppSource->mSrcImg.w, mppSource->mSrcImg.h,
2236                             mppSource->mSrcImg.format);
2237 
2238                     if (mppSource->mSrcImg.compressionInfo.type == COMP_TYPE_AFBC)
2239                         frame->setAttribute(j, AcrylicCanvas::ATTR_COMPRESSED);
2240 
2241                     hwc_rect_t src_area;
2242                     src_area.left = mppSource->mSrcImg.x;
2243                     src_area.top = mppSource->mSrcImg.y;
2244                     src_area.right = mppSource->mSrcImg.x + mppSource->mSrcImg.w;
2245                     src_area.bottom = mppSource->mSrcImg.y + mppSource->mSrcImg.h;
2246 
2247                     hwc_rect_t out_area;
2248                     out_area.left = mppSource->mMidImg.x;
2249                     out_area.top = mppSource->mMidImg.y;
2250                     out_area.right = mppSource->mMidImg.x + mppSource->mMidImg.w;
2251                     out_area.bottom = mppSource->mMidImg.y + mppSource->mMidImg.h;
2252 
2253                     frame->setTransfer(j, src_area, out_area, mppSource->mSrcImg.transform);
2254                 }
2255                 uint32_t format = mpp->mAssignedSources[0]->mMidImg.format;
2256                 bool hasSolidColorLayer = false;
2257                 if (mpp->mNeedSolidColorLayer) {
2258                     format = DEFAULT_MPP_DST_FORMAT;
2259                     hasSolidColorLayer = true;
2260                 }
2261 
2262                 frame->setTargetDimension(mpp->mAssignedDisplay->mXres,
2263                         mpp->mAssignedDisplay->mYres, format, hasSolidColorLayer);
2264 
2265                 assignedInstanceIndex++;
2266             }
2267         }
2268         if ((mpp = getExynosMPP(MPP_LOGICAL_G2D_RGB)) != NULL)
2269             mpp->mAcrylicHandle->requestPerformanceQoS(&request);
2270         else
2271             HWC_LOGE(NULL,"getExynosMPP(MPP_LOGICAL_G2D_RGB) failed");
2272     }
2273     return ret;
2274 }
2275 
2276 /*
2277  * Get used capacity of the resource that abstracts same HW resource
2278  * but it is different instance with mpp
2279  */
getResourceUsedCapa(ExynosMPP & mpp)2280 float ExynosResourceManager::getResourceUsedCapa(ExynosMPP &mpp)
2281 {
2282     float usedCapa = 0;
2283     if (mpp.mCapacity < 0)
2284         return usedCapa;
2285 
2286     HDEBUGLOGD(eDebugResourceAssigning, "%s:: [%s][%d] mpp[%d, %d]", __func__, mpp.mName.string(),
2287                mpp.mLogicalIndex, mpp.mPhysicalType, mpp.mPhysicalIndex);
2288 
2289     if (mpp.mMPPType == MPP_TYPE_OTF) {
2290         for (uint32_t i = 0; i < mOtfMPPs.size(); i++) {
2291             if ((mpp.mPhysicalType == mOtfMPPs[i]->mPhysicalType) &&
2292                 (mpp.mPhysicalIndex == mOtfMPPs[i]->mPhysicalIndex)) {
2293                 usedCapa += mOtfMPPs[i]->mUsedCapacity;
2294             }
2295         }
2296     } else {
2297         for (uint32_t i = 0; i < mM2mMPPs.size(); i++) {
2298             if ((mpp.mPhysicalType == mM2mMPPs[i]->mPhysicalType) &&
2299                 (mpp.mPhysicalIndex == mM2mMPPs[i]->mPhysicalIndex)) {
2300                 usedCapa += mM2mMPPs[i]->mUsedCapacity;
2301             }
2302         }
2303     }
2304 
2305     HDEBUGLOGD(eDebugResourceAssigning, "\t[%s][%d] mpp usedCapa: %f", mpp.mName.string(),
2306                mpp.mLogicalIndex, usedCapa);
2307     return usedCapa;
2308 }
2309 
enableMPP(uint32_t physicalType,uint32_t physicalIndex,uint32_t logicalIndex,uint32_t enable)2310 void ExynosResourceManager::enableMPP(uint32_t physicalType, uint32_t physicalIndex, uint32_t logicalIndex, uint32_t enable)
2311 {
2312     for (uint32_t i = 0; i < mOtfMPPs.size(); i++) {
2313         if ((mOtfMPPs[i]->mPhysicalType == physicalType) &&
2314             (mOtfMPPs[i]->mPhysicalIndex == physicalIndex) &&
2315             (mOtfMPPs[i]->mLogicalIndex == logicalIndex)) {
2316             mOtfMPPs[i]->mEnable = !!(enable);
2317             return;
2318         }
2319     }
2320 
2321     for (uint32_t i = 0; i < mM2mMPPs.size(); i++) {
2322         if ((mM2mMPPs[i]->mPhysicalType == physicalType) &&
2323             (mM2mMPPs[i]->mPhysicalIndex == physicalIndex) &&
2324             (mM2mMPPs[i]->mLogicalIndex == logicalIndex)) {
2325             mM2mMPPs[i]->mEnable = !!(enable);
2326             return;
2327         }
2328     }
2329 }
2330 
setScaleDownRatio(uint32_t physicalType,uint32_t physicalIndex,uint32_t logicalIndex,uint32_t scaleDownRatio)2331 void ExynosResourceManager::setScaleDownRatio(uint32_t physicalType,
2332         uint32_t physicalIndex, uint32_t logicalIndex, uint32_t scaleDownRatio)
2333 {
2334     ExynosMPP *findMpp = nullptr;
2335 
2336     auto mpp_compare = [=](ExynosMPP *mpp)->bool {
2337         return ((mpp->mPhysicalType == physicalType) &&
2338                 (mpp->mPhysicalIndex == physicalIndex) &&
2339                 (mpp->mLogicalIndex == logicalIndex));
2340     };
2341 
2342     auto otfMPP = std::find_if(mOtfMPPs.begin(), mOtfMPPs.end(),
2343             mpp_compare);
2344     if (otfMPP != mOtfMPPs.end()) {
2345         findMpp = *otfMPP;
2346     } else {
2347         auto m2mMPP = std::find_if(mM2mMPPs.begin(), mM2mMPPs.end(),
2348                 mpp_compare);
2349         findMpp = m2mMPP == mM2mMPPs.end() ? nullptr : *m2mMPP;
2350     }
2351 
2352     if (findMpp == nullptr) {
2353         ALOGE("%s:: Invalid mpp (type: %d, index: %d, %d)",
2354                 __func__, physicalType, physicalIndex, logicalIndex);
2355         return;
2356     }
2357     for (uint32_t i = RESTRICTION_RGB; i < RESTRICTION_MAX; i++) {
2358         findMpp->mDstSizeRestrictions[i].maxDownScale = scaleDownRatio;
2359     }
2360 }
2361 
prepareResources()2362 int32_t ExynosResourceManager::prepareResources()
2363 {
2364     int ret = NO_ERROR;
2365     HDEBUGLOGD(eDebugResourceManager, "This is first validate");
2366     if ((ret = resetResources()) != NO_ERROR) {
2367         HWC_LOGE(NULL,"%s:: resetResources() error (%d)",
2368                 __func__, ret);
2369         return ret;
2370     }
2371     if ((ret = preAssignResources()) != NO_ERROR) {
2372         HWC_LOGE(NULL,"%s:: preAssignResources() error (%d)",
2373                 __func__, ret);
2374         return ret;
2375     }
2376 
2377     setDisplaysTDMInfo();
2378 
2379     return ret;
2380 }
2381 
finishAssignResourceWork()2382 int32_t ExynosResourceManager::finishAssignResourceWork()
2383 {
2384 	int ret = NO_ERROR;
2385     if ((ret = updateResourceState()) != NO_ERROR) {
2386         HWC_LOGE(NULL,"%s:: stopUnAssignedResource() error (%d)",
2387                 __func__, ret);
2388         return ret;
2389     }
2390 
2391     mDevice->clearGeometryChanged();
2392     return ret;
2393 }
2394 
initResourcesState(ExynosDisplay * display)2395 int32_t ExynosResourceManager::initResourcesState(ExynosDisplay *display)
2396 {
2397     int ret = 0;
2398 
2399     if (mDevice->isFirstValidate()) {
2400         HDEBUGLOGD(eDebugResourceManager, "This is first validate");
2401         if (exynosHWCControl.displayMode < DISPLAY_MODE_NUM)
2402             mDevice->mDisplayMode = exynosHWCControl.displayMode;
2403 
2404         if ((ret = prepareResources()) != NO_ERROR) {
2405             HWC_LOGE(display, "%s:: prepareResources() error (%d)",
2406                     __func__, ret);
2407             return ret;
2408         }
2409         preAssignWindows(display);
2410 
2411     }
2412 
2413     return NO_ERROR;
2414 }
2415 
makeSizeRestrictions(uint32_t mppId,const restriction_size_t & size,restriction_classification_t format)2416 void ExynosResourceManager::makeSizeRestrictions(uint32_t mppId, const restriction_size_t &size,
2417                                                  restriction_classification_t format) {
2418     mSizeRestrictions[format][mSizeRestrictionCnt[format]].key.hwType = static_cast<mpp_phycal_type_t>(mppId);
2419     mSizeRestrictions[format][mSizeRestrictionCnt[format]].key.nodeType = NODE_SRC;
2420     mSizeRestrictions[format][mSizeRestrictionCnt[format]].key.format = HAL_PIXEL_FORMAT_NONE;
2421     mSizeRestrictions[format][mSizeRestrictionCnt[format]].key.reserved = 0;
2422     mSizeRestrictions[format][mSizeRestrictionCnt[format]++].sizeRestriction = size;
2423 
2424     mSizeRestrictions[format][mSizeRestrictionCnt[format]].key.hwType = static_cast<mpp_phycal_type_t>(mppId);
2425     mSizeRestrictions[format][mSizeRestrictionCnt[format]].key.nodeType = NODE_DST;
2426     mSizeRestrictions[format][mSizeRestrictionCnt[format]].key.format = HAL_PIXEL_FORMAT_NONE;
2427     mSizeRestrictions[format][mSizeRestrictionCnt[format]].key.reserved = 0;
2428     mSizeRestrictions[format][mSizeRestrictionCnt[format]++].sizeRestriction = size;
2429 
2430     HDEBUGLOGD(eDebugDefault, "MPP : %s, %d, %d, %d, %d, %d, %d, %d, %d, %d, %d, %d, %d, %d, %d, %d, %d",
2431             getMPPStr(mppId).string(),
2432             size.maxDownScale,
2433             size.maxUpScale,
2434             size.maxFullWidth,
2435             size.maxFullHeight,
2436             size.minFullWidth,
2437             size.minFullHeight,
2438             size.fullWidthAlign,
2439             size.fullHeightAlign,
2440             size.maxCropWidth,
2441             size.maxCropHeight,
2442             size.minCropWidth,
2443             size.minCropHeight,
2444             size.cropXAlign,
2445             size.cropYAlign,
2446             size.cropWidthAlign,
2447             size.cropHeightAlign);
2448 }
2449 
makeFormatRestrictions(restriction_key_t table)2450 void ExynosResourceManager::makeFormatRestrictions(restriction_key_t table) {
2451 
2452     mFormatRestrictions[mFormatRestrictionCnt] = table;
2453 
2454     HDEBUGLOGD(eDebugDefault, "MPP : %s, %d, %s, %d",
2455                getMPPStr(mFormatRestrictions[mFormatRestrictionCnt].hwType).string(),
2456                mFormatRestrictions[mFormatRestrictionCnt].nodeType,
2457                getFormatStr(mFormatRestrictions[mFormatRestrictionCnt].format, COMP_TYPE_MASK)
2458                        .string(),
2459                mFormatRestrictions[mFormatRestrictionCnt].reserved);
2460     mFormatRestrictionCnt++;
2461 }
2462 
makeAcrylRestrictions(mpp_phycal_type_t type)2463 void ExynosResourceManager::makeAcrylRestrictions(mpp_phycal_type_t type){
2464 
2465     Acrylic *arc = NULL;
2466     const HW2DCapability *cap;
2467 
2468     if (type == MPP_MSC)
2469         arc = Acrylic::createScaler();
2470     else if (type == MPP_G2D)
2471         arc = Acrylic::createCompositor();
2472     else {
2473         ALOGE("Unknown MPP");
2474         return;
2475     }
2476 
2477     cap = &arc->getCapabilities();
2478 
2479     /* format restriction */
2480     std::unordered_set<int32_t> supportedHalFormats;
2481     for (uint32_t i = 0; i < FORMAT_MAX_CNT; i++) {
2482         if (cap->isFormatSupported(exynos_format_desc[i].halFormat)) {
2483             /* Not add same hal pixel format */
2484             if (supportedHalFormats.find(exynos_format_desc[i].halFormat) !=
2485                     supportedHalFormats.end())
2486                 continue;
2487             restriction_key_t queried_format;
2488             queried_format.hwType = type;
2489             queried_format.nodeType = NODE_NONE;
2490             queried_format.format = exynos_format_desc[i].halFormat;
2491             queried_format.reserved = 0;
2492             makeFormatRestrictions(queried_format);
2493             supportedHalFormats.insert(exynos_format_desc[i].halFormat);
2494         }
2495     }
2496 
2497     /* RGB size restrictions */
2498     restriction_size rSize;
2499     rSize.maxDownScale = cap->supportedMinMinification().hori;
2500     rSize.maxUpScale = cap->supportedMaxMagnification().hori;
2501     rSize.maxFullWidth = cap->supportedMaxSrcDimension().hori;
2502     rSize.maxFullHeight = cap->supportedMaxSrcDimension().vert;
2503     rSize.minFullWidth = cap->supportedMinSrcDimension().hori;
2504     rSize.minFullHeight = cap->supportedMinSrcDimension().vert;
2505     rSize.fullWidthAlign = cap->supportedDimensionAlign().hori;
2506     rSize.fullHeightAlign = cap->supportedDimensionAlign().vert;
2507     rSize.maxCropWidth = cap->supportedMaxSrcDimension().hori;
2508     rSize.maxCropHeight = cap->supportedMaxSrcDimension().vert;
2509     rSize.minCropWidth = cap->supportedMinSrcDimension().hori;
2510     rSize.minCropHeight = cap->supportedMinSrcDimension().vert;
2511     rSize.cropXAlign = cap->supportedDimensionAlign().hori;
2512     rSize.cropYAlign = cap->supportedDimensionAlign().vert;
2513     rSize.cropWidthAlign = cap->supportedDimensionAlign().hori;
2514     rSize.cropHeightAlign = cap->supportedDimensionAlign().vert;
2515 
2516     makeSizeRestrictions(type, rSize, RESTRICTION_RGB);
2517 
2518     /* YUV size restrictions */
2519     rSize.fullWidthAlign = max(static_cast<uint32_t>(cap->supportedDimensionAlign().hori),
2520             YUV_CHROMA_H_SUBSAMPLE);
2521     rSize.fullHeightAlign = max(static_cast<uint32_t>(cap->supportedDimensionAlign().vert),
2522             YUV_CHROMA_V_SUBSAMPLE);
2523     rSize.cropXAlign = max(static_cast<uint32_t>(cap->supportedDimensionAlign().hori),
2524             YUV_CHROMA_H_SUBSAMPLE);
2525     rSize.cropYAlign = max(static_cast<uint32_t>(cap->supportedDimensionAlign().vert),
2526             YUV_CHROMA_V_SUBSAMPLE);
2527     rSize.cropWidthAlign = max(static_cast<uint32_t>(cap->supportedDimensionAlign().hori),
2528             YUV_CHROMA_H_SUBSAMPLE);
2529     rSize.cropHeightAlign = max(static_cast<uint32_t>(cap->supportedDimensionAlign().vert),
2530             YUV_CHROMA_V_SUBSAMPLE);
2531 
2532     makeSizeRestrictions(type, rSize, RESTRICTION_YUV);
2533 
2534     delete arc;
2535 }
2536 
getPhysicalType(int ch) const2537 mpp_phycal_type_t ExynosResourceManager::getPhysicalType(int ch) const {
2538 
2539     for (int i=0; i < MAX_DECON_DMA_TYPE; i++){
2540         if(idma_channel_map[i].channel == ch)
2541             return idma_channel_map[i].type;
2542     }
2543 
2544     return MPP_P_TYPE_MAX;
2545 }
2546 
getOtfMPPWithChannel(int ch)2547 ExynosMPP* ExynosResourceManager::getOtfMPPWithChannel(int ch)
2548 {
2549     ExynosMPP *otfMPP = NULL;
2550 
2551     for (int i=0; i < MAX_DECON_DMA_TYPE; i++){
2552         if(idma_channel_map[i].channel == ch) {
2553             otfMPP = getExynosMPP(idma_channel_map[i].type, idma_channel_map[i].index);
2554             break;
2555         }
2556     }
2557     return otfMPP;
2558 }
2559 
updateRestrictions()2560 void ExynosResourceManager::updateRestrictions() {
2561 
2562     if (mDevice->mDeviceInterface->getUseQuery() == true) {
2563         std::unordered_set<uint32_t> checkDuplicateMPP;
2564         for (const auto unit: AVAILABLE_M2M_MPP_UNITS) {
2565             if (checkDuplicateMPP.find(unit.physicalType) ==
2566                     checkDuplicateMPP.end())  {
2567                 makeAcrylRestrictions(static_cast<mpp_phycal_type_t>(unit.physicalType));
2568                 checkDuplicateMPP.insert(unit.physicalType);
2569             }
2570         }
2571     } else {
2572         mFormatRestrictionCnt = sizeof(restriction_format_table)/sizeof(restriction_key);
2573         for (uint32_t i = 0 ; i < mFormatRestrictionCnt; i++) {
2574             mFormatRestrictions[i].hwType = restriction_format_table[i].hwType;
2575             mFormatRestrictions[i].nodeType = restriction_format_table[i].nodeType;
2576             mFormatRestrictions[i].format = restriction_format_table[i].format;
2577             mFormatRestrictions[i].reserved = restriction_format_table[i].reserved;
2578         }
2579 
2580         // i = RGB, YUV
2581         // j = Size restriction count for each format (YUV, RGB)
2582         for (uint32_t i = 0; i < sizeof(restriction_tables)/sizeof(restriction_table_element); i++) {
2583             mSizeRestrictionCnt[i] = restriction_tables[i].table_element_size;
2584             for (uint32_t j = 0; j < mSizeRestrictionCnt[i]; j++) {
2585                 memcpy(&mSizeRestrictions[i][j], &restriction_tables[i].table[j],
2586                         sizeof(mSizeRestrictions[i][j]));
2587             }
2588         }
2589     }
2590 
2591     ExynosDisplay *display = NULL;
2592     bool isExistSecondaryDisplay = false;
2593 
2594     for (size_t i = 1; i < mDevice->mDisplays.size(); i++) {
2595         display = mDevice->mDisplays[i];
2596         if ((display->mType == HWC_DISPLAY_PRIMARY) && (display->mIndex == 1))
2597             isExistSecondaryDisplay = true;
2598     }
2599 
2600     for (uint32_t i = 0; i < mOtfMPPs.size(); i++) {
2601         // mAttr should be updated with updated feature_table
2602         mOtfMPPs[i]->updateAttr();
2603         mOtfMPPs[i]->setupRestriction();
2604         if (!isExistSecondaryDisplay) {
2605             /*
2606              * If there is no Secondary Display, the pre-assigned resources for Secondary Display
2607              * are pre-assigned to Primary Display.
2608              */
2609             mOtfMPPs[i]->updatePreassignedDisplay(HWC_DISPLAY_SECONDARY_BIT, HWC_DISPLAY_PRIMARY_BIT);
2610         }
2611     }
2612 
2613     for (uint32_t i = 0; i < mM2mMPPs.size(); i++) {
2614         // mAttr should be updated with updated feature_table
2615         mM2mMPPs[i]->updateAttr();
2616         mM2mMPPs[i]->setupRestriction();
2617         if (!isExistSecondaryDisplay)
2618             mM2mMPPs[i]->updatePreassignedDisplay(HWC_DISPLAY_SECONDARY_BIT, HWC_DISPLAY_PRIMARY_BIT);
2619     }
2620 }
2621 
getFeatureTableSize() const2622 uint32_t ExynosResourceManager::getFeatureTableSize() const
2623 {
2624     return sizeof(feature_table)/sizeof(feature_support_t);
2625 }
2626 
hasHDR10PlusMPP()2627 bool ExynosResourceManager::hasHDR10PlusMPP() {
2628 
2629     for (uint32_t i = 0; i < mOtfMPPs.size(); i++) {
2630         if (mOtfMPPs[i] == NULL) continue;
2631         if (mOtfMPPs[i]->mAttr & MPP_ATTR_HDR10PLUS)
2632             return true;
2633     }
2634     for (uint32_t i = 0; i < mM2mMPPs.size(); i++) {
2635         if (mM2mMPPs[i] == NULL) continue;
2636         if (mM2mMPPs[i]->mAttr & MPP_ATTR_HDR10PLUS)
2637             return true;
2638     }
2639 
2640     return false;
2641 }
2642 
getAssignedCapacity(uint32_t physicalType)2643 float ExynosResourceManager::getAssignedCapacity(uint32_t physicalType)
2644 {
2645     float totalCapacity = 0;
2646 
2647     for (size_t i = 0; i < mM2mMPPs.size(); i++) {
2648         if (mM2mMPPs[i]->mPhysicalType == physicalType)
2649             totalCapacity += mM2mMPPs[i]->getAssignedCapacity();
2650     }
2651     return totalCapacity;
2652 }
2653 
getM2MCapa(uint32_t physicalType)2654 float ExynosResourceManager::getM2MCapa(uint32_t physicalType)
2655 {
2656     float ret = 0;
2657     for (size_t i = 0; i < mM2mMPPs.size(); i++) {
2658         if (mM2mMPPs[i]->mPhysicalType == physicalType)
2659             return mM2mMPPs[i]->mCapacity;
2660     }
2661 
2662     return ret;
2663 }
2664 
dump(String8 & result) const2665 void ExynosResourceManager::dump(String8 &result) const {
2666     result.appendFormat("Resource Manager:\n");
2667 
2668     result.appendFormat("[RGB Restrictions]\n");
2669     dump(RESTRICTION_RGB, result);
2670 
2671     result.appendFormat("[YUV Restrictions]\n");
2672     dump(RESTRICTION_YUV, result);
2673 }
2674 
dump(const restriction_classification_t classification,String8 & result) const2675 void ExynosResourceManager::dump(const restriction_classification_t classification,
2676                                  String8 &result) const {
2677     const auto &restrictions = mSizeRestrictions[classification];
2678     const auto &restrictionCnt = mSizeRestrictionCnt[classification];
2679 
2680     for (int i = 0; i < restrictionCnt; ++i) {
2681         result.appendFormat("HW-Node %u-%u:\n", restrictions[i].key.hwType,
2682                             restrictions[i].key.nodeType);
2683         if (i > 0 && restrictions[i].sizeRestriction == restrictions[i - 1].sizeRestriction) {
2684             result.append("Same as above\n");
2685         } else {
2686             ::dump(restrictions[i].sizeRestriction, result);
2687         }
2688         result.appendFormat("\n");
2689     }
2690 }
2691 
setM2MCapa(uint32_t physicalType,uint32_t capa)2692 void ExynosResourceManager::setM2MCapa(uint32_t physicalType, uint32_t capa)
2693 {
2694     for (size_t i = 0; i < mM2mMPPs.size(); i++) {
2695         if (mM2mMPPs[i]->mPhysicalType == physicalType)
2696             mM2mMPPs[i]->mCapacity = capa;
2697     }
2698 }
2699 
isAssignable(ExynosMPP * candidateMPP,ExynosDisplay * display,struct exynos_image & src,struct exynos_image & dst,ExynosMPPSource * mppSrc)2700 bool ExynosResourceManager::isAssignable(ExynosMPP *candidateMPP, ExynosDisplay *display,
2701                                          struct exynos_image &src, struct exynos_image &dst,
2702                                          ExynosMPPSource *mppSrc)
2703 {
2704     bool ret = true;
2705 
2706     float totalUsedCapacity = getResourceUsedCapa(*candidateMPP);
2707     ret = candidateMPP->isAssignable(display, src, dst, totalUsedCapacity);
2708 
2709     if ((ret) && (mppSrc != nullptr)) {
2710         if ((candidateMPP->mMPPType == MPP_TYPE_OTF) &&
2711             (!isHWResourceAvailable(display, candidateMPP, mppSrc))) {
2712             if (mppSrc->mSourceType == MPP_SOURCE_LAYER) {
2713                 ExynosLayer *layer = (ExynosLayer *)mppSrc;
2714                 layer->mCheckMPPFlag[candidateMPP->mLogicalType] = eMPPExeedHWResource;
2715             }
2716             ret = false;
2717         }
2718     }
2719 
2720     return ret;
2721 }
2722 
updateSupportWCG()2723 void ExynosResourceManager::updateSupportWCG()
2724 {
2725     for (uint32_t i = 0; i < mOtfMPPs.size(); i++) {
2726         if (mOtfMPPs[i] == NULL) continue;
2727         if (mOtfMPPs[i]->mAttr & (MPP_ATTR_WCG | MPP_ATTR_HDR10)) mDeviceSupportWCG = true;
2728     }
2729     for (uint32_t i = 0; i < mM2mMPPs.size(); i++) {
2730         if (mM2mMPPs[i] == NULL) continue;
2731         if (mM2mMPPs[i]->mAttr & (MPP_ATTR_WCG | MPP_ATTR_HDR10)) mDeviceSupportWCG = true;
2732     }
2733 }
2734 
needHdrProcessing(ExynosDisplay * display,exynos_image & srcImg,exynos_image & dstImg)2735 bool ExynosResourceManager::needHdrProcessing(ExynosDisplay *display, exynos_image &srcImg,
2736                                               exynos_image &dstImg)
2737 {
2738     if (!deviceSupportWCG()) return false;
2739 
2740     return true;
2741 }
2742 
needHWResource(ExynosDisplay * display,exynos_image & srcImg,exynos_image & dstImg,tdm_attr_t attr)2743 uint32_t ExynosResourceManager::needHWResource(ExynosDisplay *display, exynos_image &srcImg,
2744                                                exynos_image &dstImg, tdm_attr_t attr)
2745 {
2746     uint32_t ret = 0;
2747 
2748     switch (attr) {
2749         case TDM_ATTR_SBWC:
2750             ret = (srcImg.compressionInfo.type == COMP_TYPE_SBWC) ? 1 : 0;
2751             break;
2752         case TDM_ATTR_AFBC:
2753             ret = (srcImg.compressionInfo.type == COMP_TYPE_AFBC) ? 1 : 0;
2754             break;
2755         case TDM_ATTR_ITP:
2756             ret = (isFormatYUV(srcImg.format)) ? 1 : 0;
2757             break;
2758         case TDM_ATTR_WCG:
2759             ret = (srcImg.needPreblending) ? 1 : 0;
2760             break;
2761         case TDM_ATTR_ROT_90:
2762             ret = ((srcImg.transform & HAL_TRANSFORM_ROT_90) == 0) ? 0 : 1;
2763             break;
2764         case TDM_ATTR_SCALE: {
2765             bool isPerpendicular = !!(srcImg.transform & HAL_TRANSFORM_ROT_90);
2766             if (isPerpendicular) {
2767                 ret = ((srcImg.w != dstImg.h) || (srcImg.h != dstImg.w)) ? 1 : 0;
2768             } else {
2769                 ret = ((srcImg.w != dstImg.w) || (srcImg.h != dstImg.h)) ? 1 : 0;
2770             }
2771         } break;
2772         default:
2773             ret = 0;
2774             break;
2775     }
2776 
2777     return ret;
2778 }
2779