summaryrefslogtreecommitdiff
path: root/hwc2/Hwc2Display.cpp (plain)
blob: 154d807cd9c27fe7975dd67fee193f8ea3f255ee
1/*
2 * Copyright (c) 2017 Amlogic, Inc. All rights reserved.
3 *
4 * This source code is subject to the terms and conditions defined in the
5 * file 'LICENSE' which is part of this source code package.
6 *
7 * Description:
8 */
9#include <hardware/hwcomposer2.h>
10#include <inttypes.h>
11
12#include "Hwc2Display.h"
13#include "Hwc2Layer.h"
14#include "Hwc2Base.h"
15
16#include <DrmTypes.h>
17#include <HwcConfig.h>
18#include <MesonLog.h>
19#include <DebugHelper.h>
20#include <Composition.h>
21#include <IComposer.h>
22#include <ComposerFactory.h>
23#include <CompositionStrategyFactory.h>
24#include <EventThread.h>
25#include <systemcontrol.h>
26
27#include "am_gralloc_ext.h"
28
29#include "CopyProcessor.h"
30
31Hwc2Display::Hwc2Display(std::shared_ptr<Hwc2DisplayObserver> observer) {
32 mObserver = observer;
33 mForceClientComposer = false;
34 mPowerMode = std::make_shared<HwcPowerMode>();
35 mSignalHpd = false;
36 mValidateDisplay = false;
37 mVsyncState = false;
38 memset(&mHdrCaps, 0, sizeof(mHdrCaps));
39 memset(mColorMatrix, 0, sizeof(float) * 16);
40 memset(&mCalibrateCoordinates, 0, sizeof(int) * 4);
41}
42
43Hwc2Display::~Hwc2Display() {
44 mLayers.clear();
45 mPlanes.clear();
46 mComposers.clear();
47
48 mCrtc.reset();
49 mConnector.reset();
50 mObserver.reset();
51 mCompositionStrategy.reset();
52 mPresentCompositionStg.reset();
53
54 mVsync.reset();
55 mModeMgr.reset();
56
57 if (mPostProcessor != NULL)
58 mPostProcessor->stop();
59 mPostProcessor.reset();
60}
61
62int32_t Hwc2Display::setModeMgr(std::shared_ptr<HwcModeMgr> & mgr) {
63 MESON_LOG_FUN_ENTER();
64 std::lock_guard<std::mutex> lock(mMutex);
65 mModeMgr = mgr;
66
67 if (mModeMgr->getDisplayMode(mDisplayMode) == 0) {
68 mPowerMode->setConnectorStatus(true);
69 }
70 MESON_LOG_FUN_LEAVE();
71 return 0;
72}
73
74int32_t Hwc2Display::initialize() {
75 MESON_LOG_FUN_ENTER();
76 std::lock_guard<std::mutex> lock(mMutex);
77
78 /*add valid composers*/
79 std::shared_ptr<IComposer> composer;
80 ComposerFactory::create(MESON_CLIENT_COMPOSER, composer);
81 mComposers.emplace(MESON_CLIENT_COMPOSER, std::move(composer));
82 ComposerFactory::create(MESON_DUMMY_COMPOSER, composer);
83 mComposers.emplace(MESON_DUMMY_COMPOSER, std::move(composer));
84#if defined(HWC_ENABLE_GE2D_COMPOSITION)
85 //TODO: havenot finish ge2d composer.
86 ComposerFactory::create(MESON_GE2D_COMPOSER, composer);
87 mComposers.emplace(MESON_GE2D_COMPOSER, std::move(composer));
88#endif
89 ComposerFactory::create(MESON_DI_COMPOSER, composer);
90 mComposers.emplace(MESON_DI_COMPOSER, std::move(composer));
91
92 initLayerIdGenerator();
93
94 MESON_LOG_FUN_LEAVE();
95 return 0;
96}
97
98int32_t Hwc2Display::setDisplayResource(
99 std::shared_ptr<HwDisplayCrtc> & crtc,
100 std::shared_ptr<HwDisplayConnector> & connector,
101 std::vector<std::shared_ptr<HwDisplayPlane>> & planes) {
102 MESON_LOG_FUN_ENTER();
103 std::lock_guard<std::mutex> lock(mMutex);
104
105 mCrtc = crtc;
106 mPlanes = planes;
107 mConnector = connector;
108
109 /*update composition strategy.*/
110 uint32_t strategyFlags = 0;
111 int osdPlanes = 0;
112 for (auto it = mPlanes.begin(); it != mPlanes.end(); ++ it) {
113 if ((*it)->getPlaneType() == OSD_PLANE) {
114 osdPlanes ++;
115 if (osdPlanes > 1) {
116 strategyFlags |= MULTI_PLANES_WITH_DI;
117 break;
118 }
119 }
120 }
121 auto newCompositionStrategy =
122 CompositionStrategyFactory::create(SIMPLE_STRATEGY, strategyFlags);
123 if (newCompositionStrategy != mCompositionStrategy) {
124 MESON_LOGD("Update composition %s -> %s",
125 mCompositionStrategy != NULL ? mCompositionStrategy->getName() : "NULL",
126 newCompositionStrategy->getName());
127 mCompositionStrategy = newCompositionStrategy;
128 }
129
130 mConnector->getHdrCapabilities(&mHdrCaps);
131#ifdef HWC_HDR_METADATA_SUPPORT
132 mCrtc->getHdrMetadataKeys(mHdrKeys);
133#endif
134
135 MESON_LOG_FUN_LEAVE();
136 return 0;
137}
138
139int32_t Hwc2Display::setPostProcessor(
140 std::shared_ptr<HwcPostProcessor> processor) {
141 std::lock_guard<std::mutex> lock(mMutex);
142 mPostProcessor = processor;
143 mProcessorFlags = 0;
144 return 0;
145}
146
147int32_t Hwc2Display::setVsync(std::shared_ptr<HwcVsync> vsync) {
148 std::lock_guard<std::mutex> lock(mMutex);
149 if (mVsync != vsync) {
150 if (mVsync.get()) {
151 mVsync->setEnabled(false);
152 mVsync->setObserver(NULL);
153 } else {
154 mVsync = vsync;
155 mVsync->setObserver(this);
156 mVsync->setEnabled(mVsyncState);
157 }
158 }
159
160 return 0;
161}
162
163/*
164 * Make sure all display planes are blank (since there is no layer)
165 *
166 * If composer service died, surfaceflinger will restart and frameBufferSurface will
167 * be recreated. But one framebuffer will be hold by the osd driver. If cma ion memory
168 * only configed to triple size of FrameBuffer, there will be one non continuous FrameBuffer
169 * and lead to messed display.
170 */
171int32_t Hwc2Display::blankDisplay() {
172 MESON_LOGD("blank all display planes");
173 std::lock_guard<std::mutex> lock(mMutex);
174
175 for (auto it = mPlanes.begin(); it != mPlanes.end(); ++ it) {
176 (*it)->setPlane(NULL, HWC_PLANE_FAKE_ZORDER, BLANK_FOR_NO_CONTENT);
177 }
178
179 int32_t fence = -1;
180 if (mCrtc && mCrtc->pageFlip(fence) == 0) {
181 std::shared_ptr<DrmFence> outfence =
182 std::make_shared<DrmFence>(fence);
183 outfence->wait(3000);
184 }
185
186 return 0;
187}
188
189const char * Hwc2Display::getName() {
190 return mConnector->getName();
191}
192
193const drm_hdr_capabilities_t * Hwc2Display::getHdrCapabilities() {
194 mConnector->getHdrCapabilities(&mHdrCaps);
195 return &mHdrCaps;
196}
197
198void Hwc2Display::getDispMode(drm_mode_info_t & dispMode){
199 dispMode = mDisplayMode;
200}
201
202#ifdef HWC_HDR_METADATA_SUPPORT
203hwc2_error_t Hwc2Display::getFrameMetadataKeys(
204 uint32_t* outNumKeys, int32_t* outKeys) {
205 *outNumKeys = mHdrKeys.size();
206 if (NULL != outKeys) {
207 for (uint32_t i = 0; i < *outNumKeys; i++)
208 outKeys[i] = mHdrKeys[i];
209 }
210
211 return HWC2_ERROR_NONE;
212}
213#endif
214
215hwc2_error_t Hwc2Display::setVsyncEnable(hwc2_vsync_t enabled) {
216 std::lock_guard<std::mutex> lock(mMutex);
217 bool state;
218 switch (enabled) {
219 case HWC2_VSYNC_ENABLE:
220 state = true;
221 break;
222 case HWC2_VSYNC_DISABLE:
223 state = false;
224 break;
225 default:
226 MESON_LOGE("[%s]: set vsync state invalid %d.", __func__, enabled);
227 return HWC2_ERROR_BAD_PARAMETER;
228 }
229 MESON_LOGD("setVsyncEnable: %s", state ? "true" : "false");
230 mVsyncState = state;
231 if (mVsync.get())
232 mVsync->setEnabled(mVsyncState);
233 return HWC2_ERROR_NONE;
234}
235
236// HWC uses SystemControl for HDMI query / control purpose. Bacuase both parties
237// respond to the same hot plug uevent additional means of synchronization
238// are required before former can talk to the latter. To accomplish that HWC
239// shall wait for SystemControl before it can update its state and notify FWK
240// accordingly.
241void Hwc2Display::onHotplug(bool connected) {
242 bool bSendPlugOut = false;
243 MESON_LOGD("On hot plug: [%s]", connected == true ? "Plug in" : "Plug out");
244
245 {
246 std::lock_guard<std::mutex> lock(mMutex);
247 if (connected) {
248 mSignalHpd = true;
249 return;
250 }
251 mPowerMode->setConnectorStatus(false);
252 if (mObserver != NULL ) {
253 bSendPlugOut = true;
254 }
255 }
256
257 /*call hotplug out of lock, SF may call some hwc function to cause deadlock.*/
258 if (bSendPlugOut) {
259 mObserver->onHotplug(false);
260 }
261
262 /* switch to software vsync when hdmi plug out and no cvbs mode */
263 if (mConnector && mConnector->getType() == DRM_MODE_CONNECTOR_HDMI) {
264 mVsync->setSoftwareMode();
265 }
266}
267
268void Hwc2Display::onUpdate(bool bHdcp) {
269 std::lock_guard<std::mutex> lock(mMutex);
270 MESON_LOGD("On update: [%s]", bHdcp == true ? "HDCP verify success" : "HDCP verify fail");
271
272 if (bHdcp) {
273 if (mObserver != NULL) {
274 mObserver->refresh();
275 } else {
276 MESON_LOGE("No display oberserve register to display (%s)", getName());
277 }
278 }
279}
280
281void Hwc2Display::onVsync(int64_t timestamp) {
282 if (mObserver != NULL) {
283 mObserver->onVsync(timestamp);
284 } else {
285 MESON_LOGE("Hwc2Display (%p) observer is NULL", this);
286 }
287}
288
289void Hwc2Display::onModeChanged(int stage) {
290 bool bSendPlugIn = false;
291 {
292 std::lock_guard<std::mutex> lock(mMutex);
293 MESON_LOGD("On mode change state: [%s]", stage == 1 ? "Complete" : "Begin to change");
294 if (stage == 1) {
295 if (mObserver != NULL) {
296 /*plug in and set displaymode ok, update inforamtion.*/
297 if (mSignalHpd) {
298 mConnector->getHdrCapabilities(&mHdrCaps);
299#ifdef HWC_HDR_METADATA_SUPPORT
300 mCrtc->getHdrMetadataKeys(mHdrKeys);
301#endif
302 }
303
304 /*update mode success.*/
305 if (mModeMgr->getDisplayMode(mDisplayMode) == 0) {
306 MESON_LOGD("Hwc2Display::onModeChanged getDisplayMode [%s]", mDisplayMode.name);
307 mPowerMode->setConnectorStatus(true);
308 if (mSignalHpd) {
309 bSendPlugIn = true;
310 mSignalHpd = false;
311 } else {
312 /*Workaround: needed for NTS test.*/
313 if (HwcConfig::primaryHotplugEnabled()
314 && (mModeMgr->getPolicyType() == FIXED_SIZE_POLICY ||
315 mModeMgr->getPolicyType() == REAL_MODE_POLICY)) {
316 bSendPlugIn = true;
317 } else if (mModeMgr->getPolicyType() == ACTIVE_MODE_POLICY) {
318 bSendPlugIn = true;
319 } else if (mModeMgr->getPolicyType() == REAL_MODE_POLICY) {
320 bSendPlugIn = true;
321 }
322 }
323 }
324 } else {
325 MESON_LOGE("No display oberserve register to display (%s)", getName());
326 }
327 }
328 }
329 /*call hotplug out of lock, SF may call some hwc function to cause deadlock.*/
330 if (bSendPlugIn && mModeMgr->needCallHotPlug()) {
331 MESON_LOGD("onModeChanged mObserver->onHotplug(true)");
332 mObserver->onHotplug(true);
333 } else {
334 MESON_LOGD("mModeMgr->resetTags");
335 mModeMgr->resetTags();
336 }
337 /*last call refresh*/
338 mObserver->refresh();
339}
340
341/*
342LayerId is 16bits.
343Higher 8 Bits: now is 256 layer slot, the higher 8 bits is the slot index.
344Lower 8 Bits: a sequence no, used to distinguish layers have same slot index (
345which may happended a layer destoryed and at the same time a new layer created.)
346*/
347#define MAX_HWC_LAYERS (256)
348#define LAYER_SLOT_BITS (8)
349
350void Hwc2Display::initLayerIdGenerator() {
351 mLayersBitmap = std::make_shared<BitsMap>(MAX_HWC_LAYERS);
352 mLayerSeq = 0;
353}
354
355hwc2_layer_t Hwc2Display::createLayerId() {
356 hwc2_layer_t layerId = 0;
357 int idx = mLayersBitmap->getZeroBit();
358 mLayersBitmap->setBit(idx);
359
360 mLayerSeq++;
361 mLayerSeq %= MAX_HWC_LAYERS;
362
363 layerId = ((idx & (MAX_HWC_LAYERS - 1)) << LAYER_SLOT_BITS) |mLayerSeq;
364 return layerId;
365}
366
367void Hwc2Display::destroyLayerId(hwc2_layer_t id) {
368 int slotIdx = id >> LAYER_SLOT_BITS;
369 mLayersBitmap->clearBit(slotIdx);
370}
371
372hwc2_error_t Hwc2Display::createLayer(hwc2_layer_t * outLayer) {
373 std::lock_guard<std::mutex> lock(mMutex);
374
375 std::shared_ptr<Hwc2Layer> layer = std::make_shared<Hwc2Layer>();
376 uint32_t idx = createLayerId();
377 *outLayer = idx;
378 layer->setUniqueId(*outLayer);
379 mLayers.emplace(*outLayer, layer);
380
381 return HWC2_ERROR_NONE;
382}
383
384hwc2_error_t Hwc2Display::destroyLayer(hwc2_layer_t inLayer) {
385 std::lock_guard<std::mutex> lock(mMutex);
386 auto layerit = mLayers.find(inLayer);
387 if (layerit == mLayers.end())
388 return HWC2_ERROR_BAD_LAYER;
389
390 DebugHelper::getInstance().removeDebugLayer((int)inLayer);
391 mLayers.erase(inLayer);
392 destroyLayerId(inLayer);
393 return HWC2_ERROR_NONE;
394}
395
396hwc2_error_t Hwc2Display::setCursorPosition(hwc2_layer_t layer __unused,
397 int32_t x __unused, int32_t y __unused) {
398 MESON_LOG_EMPTY_FUN();
399 return HWC2_ERROR_NONE;
400}
401
402hwc2_error_t Hwc2Display::setColorTransform(const float* matrix,
403 android_color_transform_t hint) {
404 if (hint == HAL_COLOR_TRANSFORM_IDENTITY) {
405 mForceClientComposer = false;
406 memset(mColorMatrix, 0, sizeof(float) * 16);
407 } else {
408 mForceClientComposer = true;
409 memcpy(mColorMatrix, matrix, sizeof(float) * 16);
410 }
411 return HWC2_ERROR_NONE;
412}
413
414hwc2_error_t Hwc2Display::setPowerMode(hwc2_power_mode_t mode) {
415 switch(mode) {
416 case HWC2_POWER_MODE_ON:
417 case HWC2_POWER_MODE_OFF:
418 MESON_LOG_EMPTY_FUN();
419 return HWC2_ERROR_NONE;
420 case HWC2_POWER_MODE_DOZE:
421 case HWC2_POWER_MODE_DOZE_SUSPEND:
422 return HWC2_ERROR_UNSUPPORTED;
423 default:
424 return HWC2_ERROR_BAD_PARAMETER;
425 };
426}
427
428std::shared_ptr<Hwc2Layer> Hwc2Display::getLayerById(hwc2_layer_t id) {
429 std::unordered_map<hwc2_layer_t, std::shared_ptr<Hwc2Layer>>::iterator it =
430 mLayers.find(id);
431
432 if (it != mLayers.end())
433 return it->second;
434
435 return NULL;
436}
437
438hwc2_error_t Hwc2Display::collectLayersForPresent() {
439 /*
440 * 1) add reference to Layers to keep it alive during display.
441 * 2) for special layer, update its composition type.
442 * 3) sort Layers by zorder for composition.
443 */
444 mPresentLayers.reserve(10);
445
446 /*Check if layer list is changed or not*/
447 bool bUpdateLayerList = false;
448 for (auto it = mLayers.begin(); it != mLayers.end(); it++) {
449 std::shared_ptr<Hwc2Layer> layer = it->second;
450 if (layer->isUpdateZorder() == true) {
451 bUpdateLayerList = true;
452 break;
453 }
454 }
455
456 for (auto it = mLayers.begin(); it != mLayers.end(); it++) {
457 std::shared_ptr<Hwc2Layer> layer = it->second;
458 std::shared_ptr<DrmFramebuffer> buffer = layer;
459 if (bUpdateLayerList == true && layer->isUpdateZorder() == false) {
460 continue;
461 }
462 mPresentLayers.push_back(buffer);
463
464 if (isLayerHideForDebug(it->first)) {
465 layer->mCompositionType = MESON_COMPOSITION_DUMMY;
466 continue;
467 }
468
469 if (HwcConfig::isHeadlessMode()) {
470 layer->mCompositionType = MESON_COMPOSITION_DUMMY;
471 } else {
472 if (layer->mHwcCompositionType == HWC2_COMPOSITION_CLIENT) {
473 layer->mCompositionType = MESON_COMPOSITION_CLIENT;
474 } else {
475 /*
476 * Other layers need further handle:
477 * 1) HWC2_COMPOSITION_DEVICE
478 * 2) HWC2_COMPOSITION_SOLID_COLOR
479 * 3) HWC2_COMPOSITION_CURSOR
480 * 4) HWC2_COMPOSITION_SIDEBAND
481 */
482 /*composition type unknown, set to none first.*/
483 layer->mCompositionType = MESON_COMPOSITION_UNDETERMINED;
484 }
485 }
486 }
487
488 if (mPresentLayers.size() > 1) {
489 /* Sort mComposeLayers by zorder. */
490 struct {
491 bool operator() (std::shared_ptr<DrmFramebuffer> a,
492 std::shared_ptr<DrmFramebuffer> b) {
493 return a->mZorder > b->mZorder;
494 }
495 } zorderCompare;
496 std::sort(mPresentLayers.begin(), mPresentLayers.end(), zorderCompare);
497 }
498
499 return HWC2_ERROR_NONE;
500}
501
502hwc2_error_t Hwc2Display::collectPlanesForPresent() {
503 mPresentPlanes = mPlanes;
504
505 if (DebugHelper::getInstance().debugPlanes()) {
506 std::map<int, int> planeFlags;
507 DebugHelper::getInstance().getPlaneDebugFlags(planeFlags);
508
509 for (auto it = mPresentPlanes.begin(); it != mPresentPlanes.end(); it++) {
510 std::shared_ptr<HwDisplayPlane> plane = *it;
511
512 auto dbgIt = planeFlags.find(plane->getPlaneId());
513 if (dbgIt != planeFlags.end()) {
514 plane->setDebugFlag(dbgIt->second);
515 } else {
516 plane->setDebugFlag(0);
517 }
518 }
519 }
520
521 return HWC2_ERROR_NONE;
522}
523
524hwc2_error_t Hwc2Display::collectComposersForPresent() {
525 for (auto it = mComposers.begin(); it != mComposers.end(); it++) {
526 mPresentComposers.push_back(it->second);
527 }
528
529 return HWC2_ERROR_NONE;
530}
531
532hwc2_error_t Hwc2Display::collectCompositionStgForPresent() {
533 mPresentCompositionStg = mCompositionStrategy;
534 return HWC2_ERROR_NONE;
535}
536
537hwc2_error_t Hwc2Display::setCalibrateInfo(int32_t caliX,int32_t caliY,int32_t caliW,int32_t caliH){
538
539 mCalibrateCoordinates[0] = caliX;
540 mCalibrateCoordinates[1] = caliY;
541 mCalibrateCoordinates[2] = caliW;
542 mCalibrateCoordinates[3] = caliH;
543
544 return HWC2_ERROR_NONE;
545}
546
547
548int32_t Hwc2Display::getDisplayIdentificationData(uint32_t &outPort,
549 std::vector<uint8_t> &outData) {
550 int32_t ret = mConnector->getIdentificationData(outData);
551 if (0 == ret) {
552 outPort = mConnector->getId();
553 }
554 return ret;
555}
556
557int32_t Hwc2Display::loadCalibrateInfo() {
558 hwc2_config_t config;
559 int32_t configWidth;
560 int32_t configHeight;
561 if (mModeMgr->getActiveConfig(&config) != HWC2_ERROR_NONE) {
562 MESON_ASSERT(0, "[%s]: getHwcDisplayHeight failed!", __func__);
563 return -ENOENT;
564 }
565 if (mModeMgr->getDisplayAttribute(config,
566 HWC2_ATTRIBUTE_WIDTH, &configWidth) != HWC2_ERROR_NONE) {
567 MESON_ASSERT(0, "[%s]: getHwcDisplayHeight failed!", __func__);
568 return -ENOENT;
569 }
570 if (mModeMgr->getDisplayAttribute(config,
571 HWC2_ATTRIBUTE_HEIGHT, &configHeight) != HWC2_ERROR_NONE) {
572 MESON_ASSERT(0, "[%s]: getHwcDisplayHeight failed!", __func__);
573 return -ENOENT;
574 }
575
576 if (mDisplayMode.pixelW == 0 || mDisplayMode.pixelH == 0) {
577 MESON_ASSERT(0, "[%s]: Displaymode is invalid(%s, %dx%d)!",
578 __func__, mDisplayMode.name, mDisplayMode.pixelW, mDisplayMode.pixelH);
579 return -ENOENT;
580 }
581/* MESON_LOGD("(%s): loadCalibrateInfo:(%s) pixelW (%d) pixelH (%d) ", __func__,
582 mDisplayMode.name , mDisplayMode.pixelW, mDisplayMode.pixelH);*/
583 /*default info*/
584 mCalibrateInfo.framebuffer_w = configWidth;
585 mCalibrateInfo.framebuffer_h = configHeight;
586 mCalibrateInfo.crtc_display_x = mCalibrateCoordinates[0];
587 mCalibrateInfo.crtc_display_y = mCalibrateCoordinates[1];
588 mCalibrateInfo.crtc_display_w = mCalibrateCoordinates[2];
589 mCalibrateInfo.crtc_display_h = mCalibrateCoordinates[3];
590
591 return 0;
592}
593
594// Scaled display frame to the framebuffer config if necessary
595// (i.e. not at the default resolution of 1080p)
596int32_t Hwc2Display::adjustDisplayFrame() {
597 bool bNoScale = false;
598 if (mCalibrateInfo.framebuffer_w == mCalibrateInfo.crtc_display_w &&
599 mCalibrateInfo.framebuffer_h == mCalibrateInfo.crtc_display_h) {
600 bNoScale = true;
601 }
602
603 Hwc2Layer * layer;
604 for (auto it = mPresentLayers.begin() ; it != mPresentLayers.end(); it++) {
605 layer = (Hwc2Layer*)(it->get());
606 if (bNoScale) {
607 layer->mDisplayFrame = layer->mBackupDisplayFrame;
608 } else {
609 layer->mDisplayFrame.left = (int32_t)ceilf(layer->mBackupDisplayFrame.left *
610 mCalibrateInfo.crtc_display_w / mCalibrateInfo.framebuffer_w) +
611 mCalibrateInfo.crtc_display_x;
612 layer->mDisplayFrame.top = (int32_t)ceilf(layer->mBackupDisplayFrame.top *
613 mCalibrateInfo.crtc_display_h / mCalibrateInfo.framebuffer_h) +
614 mCalibrateInfo.crtc_display_y;
615 layer->mDisplayFrame.right = (int32_t)ceilf(layer->mBackupDisplayFrame.right *
616 mCalibrateInfo.crtc_display_w / mCalibrateInfo.framebuffer_w) +
617 mCalibrateInfo.crtc_display_x;
618 layer->mDisplayFrame.bottom = (int32_t)ceilf(layer->mBackupDisplayFrame.bottom *
619 mCalibrateInfo.crtc_display_h / mCalibrateInfo.framebuffer_h) +
620 mCalibrateInfo.crtc_display_y;
621 }
622 }
623
624 return 0;
625}
626
627hwc2_error_t Hwc2Display::validateDisplay(uint32_t* outNumTypes,
628 uint32_t* outNumRequests) {
629 std::lock_guard<std::mutex> lock(mMutex);
630 /*clear data used in composition.*/
631 mPresentLayers.clear();
632 mPresentComposers.clear();
633 mPresentPlanes.clear();
634 mPresentCompositionStg.reset();
635 mChangedLayers.clear();
636 mOverlayLayers.clear();
637 mFailedDeviceComp = false;
638 mSkipComposition = false;
639
640 hwc2_error_t ret = collectLayersForPresent();
641 if (ret != HWC2_ERROR_NONE) {
642 return ret;
643 }
644 ret = collectComposersForPresent();
645 if (ret != HWC2_ERROR_NONE) {
646 return ret;
647 }
648 ret = collectPlanesForPresent();
649 if (ret != HWC2_ERROR_NONE) {
650 return ret;
651 }
652 ret = collectCompositionStgForPresent();
653 if (ret != HWC2_ERROR_NONE) {
654 return ret;
655 }
656
657 /*collect composition flag*/
658 uint32_t compositionFlags = 0;
659 if (mForceClientComposer ||
660 DebugHelper::getInstance().disableUiHwc() ||
661 HwcConfig::forceClientEnabled()) {
662 compositionFlags |= COMPOSE_FORCE_CLIENT;
663 }
664
665 if (HwcConfig::secureLayerProcessEnabled()) {
666 if (!mConnector->isSecure()) {
667 compositionFlags |= COMPOSE_HIDE_SECURE_FB;
668 }
669 }
670
671 /*check power mode*/
672 if (mPowerMode->needBlankScreen(mPresentLayers.size())) {
673 if (!mPowerMode->getScreenStatus()) {
674 MESON_LOGD("Need to blank screen.");
675 mPresentLayers.clear();
676 } else {
677 mSkipComposition = true;
678 }
679 }
680 /*do composition*/
681 if (!mSkipComposition) {
682 mPowerMode->setScreenStatus(mPresentLayers.size() > 0 ? false : true);
683 /*update calibrate info.*/
684 loadCalibrateInfo();
685 /*update displayframe before do composition.*/
686 if (mPresentLayers.size() > 0)
687 adjustDisplayFrame();
688 /*setup composition strategy.*/
689 mPresentCompositionStg->setup(mPresentLayers,
690 mPresentComposers, mPresentPlanes, mCrtc, compositionFlags);
691 if (mPresentCompositionStg->decideComposition() < 0) {
692 return HWC2_ERROR_NO_RESOURCES;
693 }
694
695 /*collect changed dispplay, layer, compostiion.*/
696 ret = collectCompositionRequest(outNumTypes, outNumRequests);
697 } else {
698 /* skip Composition */
699 std::shared_ptr<IComposer> clientComposer =
700 mComposers.find(MESON_CLIENT_COMPOSER)->second;
701 clientComposer->prepare();
702 }
703
704 if (mPowerMode->getScreenStatus()) {
705 mProcessorFlags |= PRESENT_BLANK;
706 }
707
708 /* If mValidateDisplay = false, hwc will not handle presentDisplay. */
709 mValidateDisplay = true;
710
711 /*dump at end of validate, for we need check by some composition info.*/
712 bool dumpLayers = false;
713 if (DebugHelper::getInstance().logCompositionDetail()) {
714 MESON_LOGE("***CompositionFlow (%s):\n", __func__);
715 dumpLayers = true;
716 } else if (mFailedDeviceComp) {
717 MESON_LOGE("***MonitorFailedDeviceComposition: \n");
718 dumpLayers = true;
719 }
720 if (dumpLayers) {
721 String8 layersDump;
722 dumpPresentLayers(layersDump);
723 MESON_LOGE("%s", layersDump.string());
724 }
725 return ret;
726}
727
728hwc2_error_t Hwc2Display::collectCompositionRequest(
729 uint32_t* outNumTypes, uint32_t* outNumRequests) {
730 Hwc2Layer *layer;
731 /*collect display requested, and changed composition type.*/
732 for (auto it = mPresentLayers.begin() ; it != mPresentLayers.end(); it++) {
733 layer = (Hwc2Layer*)(it->get());
734 /*record composition changed layer.*/
735 hwc2_composition_t expectedHwcComposition =
736 mesonComp2Hwc2Comp(layer);
737 if (expectedHwcComposition != layer->mHwcCompositionType) {
738 mChangedLayers.push_back(layer->getUniqueId());
739 /*For debug.*/
740 if (DebugHelper::getInstance().monitorDeviceComposition() &&
741 (mPresentLayers.size() <= DebugHelper::getInstance().deviceCompositionThreshold()) &&
742 (expectedHwcComposition == HWC2_COMPOSITION_CLIENT)) {
743 mFailedDeviceComp = true;
744 }
745 }
746 if (expectedHwcComposition == HWC2_COMPOSITION_SIDEBAND || layer->mCompositionType == MESON_COMPOSITION_PLANE_AMVIDEO)
747 mProcessorFlags |= PRESENT_SIDEBAND;
748 }
749
750 /*collcet client clear layer.*/
751 std::shared_ptr<IComposer> clientComposer =
752 mComposers.find(MESON_CLIENT_COMPOSER)->second;
753 std::vector<std::shared_ptr<DrmFramebuffer>> overlayLayers;
754 if (0 == clientComposer->getOverlyFbs(overlayLayers) ) {
755 auto it = overlayLayers.begin();
756 for (; it != overlayLayers.end(); ++it) {
757 layer = (Hwc2Layer*)(it->get());
758 mOverlayLayers.push_back(layer->getUniqueId());
759 }
760 }
761
762 *outNumRequests = mOverlayLayers.size();
763 *outNumTypes = mChangedLayers.size();
764
765 return ((*outNumTypes) > 0) ? HWC2_ERROR_HAS_CHANGES : HWC2_ERROR_NONE;
766}
767
768hwc2_error_t Hwc2Display::getDisplayRequests(
769 int32_t* outDisplayRequests, uint32_t* outNumElements,
770 hwc2_layer_t* outLayers,int32_t* outLayerRequests) {
771 *outDisplayRequests = 0;
772
773 /*check if need HWC2_LAYER_REQUEST_CLEAR_CLIENT_TARGET*/
774 *outNumElements = mOverlayLayers.size();
775 if (outLayers && outLayerRequests) {
776 for (uint32_t i = 0; i < mOverlayLayers.size(); i++) {
777 outLayers[i] = mOverlayLayers[i];
778 outLayerRequests[i] = HWC2_LAYER_REQUEST_CLEAR_CLIENT_TARGET;
779 }
780 }
781
782 return HWC2_ERROR_NONE;
783}
784
785hwc2_error_t Hwc2Display::getChangedCompositionTypes(
786 uint32_t * outNumElements, hwc2_layer_t * outLayers,
787 int32_t * outTypes) {
788 *outNumElements = mChangedLayers.size();
789 if (outLayers && outTypes) {
790 for (uint32_t i = 0; i < mChangedLayers.size(); i++) {
791 std::shared_ptr<Hwc2Layer> layer = mLayers.find(mChangedLayers[i])->second;
792 outTypes[i] = mesonComp2Hwc2Comp(layer.get());
793 outLayers[i] = mChangedLayers[i];
794 }
795 }
796
797 return HWC2_ERROR_NONE;
798}
799
800hwc2_error_t Hwc2Display::acceptDisplayChanges() {
801 /* commit composition type */
802 for (auto it = mPresentLayers.begin(); it != mPresentLayers.end(); it++) {
803 Hwc2Layer * layer = (Hwc2Layer*)(it->get());
804 layer->commitCompType(mesonComp2Hwc2Comp(layer));
805 }
806
807 /* set updateZorder flag to false */
808 for (auto it = mLayers.begin(); it != mLayers.end(); it++) {
809 std::shared_ptr<Hwc2Layer> layer = it->second;
810 layer->updateZorder(false);
811 }
812
813 return HWC2_ERROR_NONE;
814}
815
816hwc2_error_t Hwc2Display::presentDisplay(int32_t* outPresentFence) {
817 std::lock_guard<std::mutex> lock(mMutex);
818
819 if (mSkipComposition) {
820 *outPresentFence = -1;
821 } else {
822 if (mValidateDisplay == false) {
823 MESON_LOGD("presentDisplay without validateDisplay");
824 return HWC2_ERROR_NONE;
825 }
826 mValidateDisplay = false;
827 int32_t outFence = -1;
828 /*Start to compose, set up plane info.*/
829 if (mPresentCompositionStg->commit() != 0) {
830 return HWC2_ERROR_NOT_VALIDATED;
831 }
832
833 #ifdef HWC_HDR_METADATA_SUPPORT
834 /*set hdr metadata info.*/
835 for (auto it = mPresentLayers.begin() ; it != mPresentLayers.end(); it++) {
836 if ((*it)->mHdrMetaData.empty() == false) {
837 mCrtc->setHdrMetadata((*it)->mHdrMetaData);
838 break;
839 }
840 }
841 #endif
842
843 /* Page flip */
844 if (mCrtc->pageFlip(outFence) < 0) {
845 return HWC2_ERROR_UNSUPPORTED;
846 }
847 if (mPostProcessor != NULL) {
848 int32_t displayFence = ::dup(outFence);
849 mPostProcessor->present(mProcessorFlags, displayFence);
850 mProcessorFlags = 0;
851 }
852
853 *outPresentFence = outFence;
854 }
855
856 /*dump debug informations.*/
857 bool dumpComposition = false;
858 if (DebugHelper::getInstance().logCompositionDetail()) {
859 MESON_LOGE("***CompositionFlow (%s):\n", __func__);
860 dumpComposition = true;
861 } else if (mFailedDeviceComp) {
862 MESON_LOGE("***MonitorFailedDeviceComposition: \n");
863 dumpComposition = true;
864 }
865 if (dumpComposition) {
866 String8 compDump;
867 mPresentCompositionStg->dump(compDump);
868 MESON_LOGE("%s", compDump.string());
869 }
870 return HWC2_ERROR_NONE;
871}
872
873hwc2_error_t Hwc2Display::getReleaseFences(uint32_t* outNumElements,
874 hwc2_layer_t* outLayers, int32_t* outFences) {
875 uint32_t num = 0;
876 bool needInfo = false;
877 if (outLayers && outFences)
878 needInfo = true;
879
880 /*
881 * Return release fence for all layers, not only DEVICE composition Layers,
882 * for we donot know if it is DEVICE compositin in last composition.
883 */
884 for (auto it = mPresentLayers.begin(); it != mPresentLayers.end(); it++) {
885 Hwc2Layer *layer = (Hwc2Layer*)(it->get());
886 num++;
887 if (needInfo) {
888 int32_t releaseFence = layer->getReleaseFence();
889 *outLayers = layer->getUniqueId();
890 *outFences = releaseFence;
891 outLayers++;
892 outFences++;
893 layer->clearReleaseFence();
894 }
895 }
896
897 *outNumElements = num;
898 return HWC2_ERROR_NONE;
899}
900
901hwc2_error_t Hwc2Display::setClientTarget(buffer_handle_t target,
902 int32_t acquireFence, int32_t dataspace, hwc_region_t damage) {
903 std::lock_guard<std::mutex> lock(mMutex);
904 /*create DrmFramebuffer for client target.*/
905 std::shared_ptr<DrmFramebuffer> clientFb = std::make_shared<DrmFramebuffer>(
906 target, acquireFence);
907 clientFb->mFbType = DRM_FB_SCANOUT;
908 clientFb->mBlendMode = DRM_BLEND_MODE_PREMULTIPLIED;
909 clientFb->mPlaneAlpha = 1.0f;
910 clientFb->mTransform = 0;
911 clientFb->mDataspace = dataspace;
912
913 /* real mode set real source crop */
914 if (HwcConfig::getModePolicy(0) == REAL_MODE_POLICY) {
915 drm_mode_info_t mode;
916 mModeMgr->getDisplayMode(mode);
917 clientFb->mSourceCrop.right = ((int32_t)mode.pixelW < clientFb->mSourceCrop.right)
918 ? mode.pixelW : clientFb->mSourceCrop.right;
919 clientFb->mSourceCrop.bottom = ((int32_t)mode.pixelH < clientFb->mSourceCrop.bottom)
920 ? mode.pixelH : clientFb->mSourceCrop.bottom;
921 }
922
923 /*client target is always full screen, just post to crtc display axis.*/
924 clientFb->mDisplayFrame.left = mCalibrateInfo.crtc_display_x;
925 clientFb->mDisplayFrame.top = mCalibrateInfo.crtc_display_y;
926 clientFb->mDisplayFrame.right = mCalibrateInfo.crtc_display_x +
927 mCalibrateInfo.crtc_display_w;
928 clientFb->mDisplayFrame.bottom = mCalibrateInfo.crtc_display_y +
929 mCalibrateInfo.crtc_display_h;
930
931 /*set framebuffer to client composer.*/
932 std::shared_ptr<IComposer> clientComposer =
933 mComposers.find(MESON_CLIENT_COMPOSER)->second;
934 if (clientComposer.get() &&
935 clientComposer->setOutput(clientFb, damage) == 0) {
936 return HWC2_ERROR_NONE;
937 }
938
939 return HWC2_ERROR_BAD_PARAMETER;
940}
941
942hwc2_error_t Hwc2Display::getDisplayConfigs(
943 uint32_t* outNumConfigs,
944 hwc2_config_t* outConfigs) {
945 if (mModeMgr != NULL) {
946 return (hwc2_error_t)mModeMgr->getDisplayConfigs(outNumConfigs, outConfigs);
947 } else {
948 MESON_LOGE("Hwc2Display getDisplayConfigs (%s) miss valid DisplayConfigure.",
949 getName());
950 return HWC2_ERROR_BAD_DISPLAY;
951 }
952}
953
954hwc2_error_t Hwc2Display::getDisplayAttribute(
955 hwc2_config_t config,
956 int32_t attribute,
957 int32_t* outValue) {
958 if (mModeMgr != NULL) {
959 return (hwc2_error_t)mModeMgr->getDisplayAttribute(
960 config, attribute, outValue, CALL_FROM_SF);
961 } else {
962 MESON_LOGE("Hwc2Display (%s) getDisplayAttribute miss valid DisplayConfigure.",
963 getName());
964 return HWC2_ERROR_BAD_DISPLAY;
965 }
966}
967
968hwc2_error_t Hwc2Display::getActiveConfig(
969 hwc2_config_t* outConfig) {
970 if (mModeMgr != NULL) {
971 return (hwc2_error_t)mModeMgr->getActiveConfig(outConfig, CALL_FROM_SF);
972 } else {
973 MESON_LOGE("Hwc2Display (%s) getActiveConfig miss valid DisplayConfigure.",
974 getName());
975 return HWC2_ERROR_BAD_DISPLAY;
976 }
977}
978
979hwc2_error_t Hwc2Display::setActiveConfig(
980 hwc2_config_t config) {
981 if (mModeMgr != NULL) {
982 return (hwc2_error_t)mModeMgr->setActiveConfig(config);
983 } else {
984 MESON_LOGE("Display (%s) setActiveConfig miss valid DisplayConfigure.",
985 getName());
986 return HWC2_ERROR_BAD_DISPLAY;
987 }
988}
989
990bool Hwc2Display::isLayerHideForDebug(hwc2_layer_t id) {
991 std::vector<int> hideLayers;
992 DebugHelper::getInstance().getHideLayers(hideLayers);
993 if (hideLayers.empty())
994 return false;
995
996 for (auto it = hideLayers.begin(); it < hideLayers.end(); it++) {
997 if (*it == (int)id)
998 return true;
999 }
1000
1001 return false;
1002}
1003
1004hwc2_error_t Hwc2Display::getDisplayCapabilities(
1005 uint32_t* outNumCapabilities, uint32_t* outCapabilities) {
1006 if (outCapabilities == nullptr) {
1007 if (mConnector->isConnected() == false)
1008 *outNumCapabilities = 1;
1009 else
1010 *outNumCapabilities = 0;
1011 } else {
1012 if (mConnector->isConnected() == false && *outNumCapabilities == 1) {
1013 outCapabilities[0] = HWC2_DISPLAY_CAPABILITY_INVALID;
1014 }
1015 }
1016 return HWC2_ERROR_NONE;
1017}
1018
1019void Hwc2Display::dumpPresentLayers(String8 & dumpstr) {
1020 dumpstr.append("----------------------------------------------------------"
1021 "-----------------------------------\n");
1022 dumpstr.append("| id | z | type |blend| alpha |t|"
1023 " AFBC | Source Crop | Display Frame |\n");
1024 for (auto it = mPresentLayers.begin(); it != mPresentLayers.end(); it++) {
1025 Hwc2Layer *layer = (Hwc2Layer*)(it->get());
1026 dumpstr.append("+------+-----+------------+-----+--------+-+--------+"
1027 "-------------------+-------------------+\n");
1028 dumpstr.appendFormat("|%6llu|%5d|%12s|%5d|%8f|%1d|%8x|%4d %4d %4d %4d"
1029 "|%4d %4d %4d %4d|\n",
1030 layer->getUniqueId(),
1031 layer->mZorder,
1032 drmFbTypeToString(layer->mFbType),
1033 layer->mBlendMode,
1034 layer->mPlaneAlpha,
1035 layer->mTransform,
1036 am_gralloc_get_vpu_afbc_mask(layer->mBufferHandle),
1037 layer->mSourceCrop.left,
1038 layer->mSourceCrop.top,
1039 layer->mSourceCrop.right,
1040 layer->mSourceCrop.bottom,
1041 layer->mDisplayFrame.left,
1042 layer->mDisplayFrame.top,
1043 layer->mDisplayFrame.right,
1044 layer->mDisplayFrame.bottom
1045 );
1046 }
1047 dumpstr.append("----------------------------------------------------------"
1048 "-----------------------------------\n");
1049}
1050
1051void Hwc2Display::dumpHwDisplayPlane(String8 &dumpstr) {
1052 if (DebugHelper::getInstance().dumpDetailInfo()) {
1053 dumpstr.append("HwDisplayPlane Info:\n");
1054 dumpstr.append("------------------------------------------------------------"
1055 "-----------------------------------------------------------------\n");
1056 dumpstr.append("| ID |Zorder| type | source crop | dis Frame"
1057 " | fd | fm | b_st | p_st | blend | alpha | op | afbc fm |\n");
1058 dumpstr.append("+-------+------+------+---------------------+-----------------"
1059 "----+----+----+------+------+-------+-------+------+----------+\n");
1060
1061 /* dump osd plane */
1062 for (auto it = mPresentPlanes.begin(); it != mPresentPlanes.end(); it++) {
1063 std::shared_ptr<HwDisplayPlane> plane = *it;
1064 if (!strncmp("OSD", plane->getName(), 3)) {
1065 plane->dump(dumpstr);
1066 }
1067 }
1068 dumpstr.append("------------------------------------------------------------"
1069 "-----------------------------------------------------------------\n");
1070 dumpstr.append("\n");
1071 }
1072}
1073
1074void Hwc2Display::dump(String8 & dumpstr) {
1075 /*update for debug*/
1076 if (DebugHelper::getInstance().debugHideLayers() ||
1077 DebugHelper::getInstance().debugPlanes()) {
1078 //ask for auto refresh for debug layers update.
1079 if (mObserver != NULL) {
1080 mObserver->refresh();
1081 }
1082 }
1083
1084 /*dump*/
1085 dumpstr.append("---------------------------------------------------------"
1086 "-----------------------------\n");
1087 dumpstr.appendFormat("Display (%s, %s) \n",
1088 getName(), mForceClientComposer ? "Client-Comp" : "HW-Comp");
1089 dumpstr.appendFormat("Power: (%d-%d) \n",
1090 mPowerMode->getMode(), mPowerMode->getScreenStatus());
1091 /*calibration info*/
1092 dumpstr.appendFormat("Calibration: (%dx%d)->(%dx%d,%dx%d)\n",
1093 mCalibrateInfo.framebuffer_w, mCalibrateInfo.framebuffer_h,
1094 mCalibrateInfo.crtc_display_x, mCalibrateInfo.crtc_display_y,
1095 mCalibrateInfo.crtc_display_w, mCalibrateInfo.crtc_display_h);
1096
1097 /* HDR info */
1098 dumpstr.append("HDR Capabilities:\n");
1099 dumpstr.appendFormat(" DolbyVision1=%d\n",
1100 mHdrCaps.DolbyVisionSupported ? 1 : 0);
1101 dumpstr.appendFormat(" HLG=%d\n",
1102 mHdrCaps.HLGSupported ? 1 : 0);
1103 dumpstr.appendFormat(" HDR10=%d, HDR10+=%d, "
1104 "maxLuminance=%d, avgLuminance=%d, minLuminance=%d\n",
1105 mHdrCaps.HDR10Supported ? 1 : 0,
1106 mHdrCaps.HDR10PlusSupported ? 1 : 0,
1107 mHdrCaps.maxLuminance,
1108 mHdrCaps.avgLuminance,
1109 mHdrCaps.minLuminance);
1110
1111 dumpstr.append("\n");
1112
1113 /* dump display configs*/
1114 mModeMgr->dump(dumpstr);
1115 dumpstr.append("\n");
1116 mVsync->dump(dumpstr);
1117 dumpstr.append("\n");
1118
1119 /*dump detail debug info*/
1120 if (DebugHelper::getInstance().dumpDetailInfo()) {
1121 /* dump composers*/
1122 dumpstr.append("Valid composers:\n");
1123 for (auto it = mPresentComposers.begin(); it != mPresentComposers.end(); it++) {
1124 dumpstr.appendFormat("%s-Composer (%p)\n", it->get()->getName(), it->get());
1125 }
1126 dumpstr.append("\n");
1127
1128 /* dump present layers info*/
1129 dumpstr.append("Present layers:\n");
1130 dumpPresentLayers(dumpstr);
1131 dumpstr.append("\n");
1132
1133 /* dump composition stragegy.*/
1134 if (mPresentCompositionStg) {
1135 mPresentCompositionStg->dump(dumpstr);
1136 dumpstr.append("\n");
1137 }
1138 }
1139
1140 dumpstr.append("\n");
1141 dumpHwDisplayPlane(dumpstr);
1142}
1143
1144int32_t Hwc2Display::captureDisplayScreen(buffer_handle_t hnd) {
1145 int ret = -1;
1146 std::shared_ptr<DrmFramebuffer> capBuffer;
1147
1148 ALOGD("hwc2Display:: captureDisplayScreen");
1149 if (mPostProcessor && hnd) {
1150 capBuffer = std::make_shared<DrmFramebuffer>(hnd, -1);
1151 //ret = mPostProcessor->getScreencapFb(capBuffer);
1152 capBuffer.reset();
1153 }
1154
1155 return ret;
1156}
1157