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