summaryrefslogtreecommitdiff
path: root/hwc2/common/devices/PhysicalDevice.cpp (plain)
blob: 85490e8e935ad646a53047aa0eaaa9d097c49130
1/*
2// Copyright (c) 2014 Intel Corporation
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// This file is modified by Amlogic, Inc. 2017.01.17.
17*/
18
19#include <fcntl.h>
20#include <inttypes.h>
21#include <HwcTrace.h>
22#include <PhysicalDevice.h>
23#include <Hwcomposer.h>
24#include <sys/ioctl.h>
25#include <sync/sync.h>
26#include <Utils.h>
27#include <HwcFenceControl.h>
28#include <cutils/properties.h>
29#include <tvp/OmxUtil.h>
30#include <framebuffer.h>
31
32#define FBIOPUT_OSD_CURSOR 0x451a
33
34namespace android {
35namespace amlogic {
36
37PhysicalDevice::PhysicalDevice(hwc2_display_t id, Hwcomposer& hwc, IComposeDeviceFactory* controlFactory)
38 : mId(id),
39 mHwc(hwc),
40 mControlFactory(controlFactory),
41 mVsyncObserver(NULL),
42 mConnectorPresent(false),
43 mSecure(false),
44 mFramebufferHnd(NULL),
45 mSystemControl(NULL),
46 mFbSlot(0),
47 mComposer(NULL),
48 mPriorFrameRetireFence(-1),
49 mClientTargetHnd(NULL),
50 mTargetAcquireFence(-1),
51 mRenderMode(GLES_COMPOSE_MODE),
52 mPreviousRenderMode(GLES_COMPOSE_MODE),
53 mIsValidated(false),
54 mIsContinuousBuf(true),
55 mDirectRenderLayerId(0),
56 mVideoOverlayLayerId(0),
57 mGE2DClearVideoRegionCount(0),
58 mGE2DComposeFrameCount(0),
59 mDirectComposeFrameCount(0),
60 mGetInitState(false),
61 mInitialized(false),
62 mOmxVideoHandle(0),
63 mFirstPostFb(true){
64 CTRACE();
65
66 switch (id) {
67 case DEVICE_PRIMARY:
68 mName = "Primary";
69 break;
70 case DEVICE_EXTERNAL:
71 mName = "External";
72 break;
73 default:
74 mName = "Unknown";
75 }
76
77 mHdrCapabilities.init = false;
78
79 // clear layers vectors.
80 mHwcSecureLayers.clear();
81 mHwcLayersChangeType.clear();
82 mHwcLayersChangeRequest.clear();
83 mHwcGlesLayers.clear();
84 mHwcLayers.clear();
85 mGE2DRenderSortedLayerIds.clear();
86
87 mHwcCurReleaseFences = mHwcPriorReleaseFences = NULL;
88}
89
90PhysicalDevice::~PhysicalDevice() {
91 WARN_IF_NOT_DEINIT();
92 clearFenceList(mHwcCurReleaseFences);
93 clearFenceList(mHwcPriorReleaseFences);
94 if (mOmxVideoHandle != 0) {
95 closeamvideo();
96 mOmxVideoHandle = 0;
97 }
98}
99
100bool PhysicalDevice::initialize() {
101 CTRACE();
102
103 if (mId != DEVICE_PRIMARY && mId != DEVICE_EXTERNAL) {
104 ETRACE("invalid device type");
105 return false;
106 }
107
108 // init Display here.
109 initDisplay();
110
111 // create vsync event observer, we only have soft vsync now...
112 mVsyncObserver = new SoftVsyncObserver(*this);
113 if (!mVsyncObserver || !mVsyncObserver->initialize()) {
114 DEINIT_AND_RETURN_FALSE("failed to create vsync observer");
115 }
116
117 UeventObserver *observer = Hwcomposer::getInstance().getUeventObserver();
118 if (observer) {
119 observer->registerListener(
120 Utils::getHdcpUeventEnvelope(),
121 hdcpEventListener,
122 this);
123 } else {
124 ETRACE("PhysicalDevice::Uevent observer is NULL");
125 }
126
127 mDisplayHdmi = new DisplayHdmi();
128 framebuffer_info_t framebufferInfo = *(mFramebufferContext->getInfo());
129 framebufferInfo.info.xres = mDisplayWidth;
130 framebufferInfo.info.yres = mDisplayHeight;
131 mDisplayHdmi->initialize(framebufferInfo);
132
133 mInitialized = true;
134 return true;
135}
136
137auto PhysicalDevice::getSystemControlService() {
138 static bool bGot = false;
139 static auto systemControl = ISystemControl::getService();
140 if (bGot) {
141 ETRACE("systemControl is already exist");
142 return systemControl;
143 }
144 mDeathRecipient = new SystemControlDeathRecipient();
145 Return<bool> linked = systemControl->linkToDeath(mDeathRecipient, /*cookie*/ 0);
146 if (!linked.isOk()) {
147 ETRACE("Transaction error in linking to system service death: %s",
148 linked.description().c_str());
149 } else if (!linked) {
150 ETRACE("Unable to link to system service death notifications");
151 } else {
152 DTRACE("Link to system service death notification successful");
153 }
154 bGot = true;
155 return systemControl;
156}
157
158void PhysicalDevice::updateDisplayInfo(char defaultMode[64]) {
159 if (!strncmp(defaultMode, "720", 3)) {
160 mDisplayWidth= FULL_WIDTH_720;
161 mDisplayHeight = FULL_HEIGHT_720;
162 } else if (!strncmp(defaultMode, "1080", 4)) {
163 mDisplayWidth = FULL_WIDTH_1080;
164 mDisplayHeight = FULL_HEIGHT_1080;
165 } else if (!strncmp(defaultMode, "4k2k", 4)) {
166 mDisplayWidth = FULL_WIDTH_4K2K;
167 mDisplayHeight = FULL_HEIGHT_4K2K;
168 }
169}
170
171void PhysicalDevice::hdcpEventListener(void *data, bool status) {
172 PhysicalDevice *pThis = (PhysicalDevice*)data;
173 if (pThis) {
174 pThis->setSecureStatus(status);
175 }
176}
177
178void PhysicalDevice::setSecureStatus(bool status) {
179 DTRACE("hdcp event: %d", status);
180 mSecure = status;
181}
182
183void PhysicalDevice::deinitialize() {
184 Mutex::Autolock _l(mLock);
185
186 DEINIT_AND_DELETE_OBJ(mVsyncObserver);
187 DEINIT_AND_DELETE_OBJ(mDisplayHdmi);
188 DEINIT_AND_DELETE_OBJ(mComposer);
189
190 if (mFramebufferContext != NULL) {
191 delete mFramebufferContext;
192 mFramebufferContext = NULL;
193 }
194
195 if (mCursorContext != NULL) {
196 delete mCursorContext;
197 mCursorContext = NULL;
198 }
199
200 mInitialized = false;
201}
202
203HwcLayer* PhysicalDevice::getLayerById(hwc2_layer_t layerId) {
204 HwcLayer* layer = NULL;
205 ssize_t index = mHwcLayers.indexOfKey(layerId);
206
207 if (index >= 0) {
208 layer = mHwcLayers.valueFor(layerId);
209 }
210
211 if (!layer) {
212 DTRACE("getLayerById %lld error!", layerId);
213 }
214 return layer;
215}
216
217int32_t PhysicalDevice::acceptDisplayChanges() {
218 HwcLayer* layer = NULL;
219
220 for (uint32_t i=0; i<mHwcLayersChangeType.size(); i++) {
221 hwc2_layer_t layerId = mHwcLayersChangeType.keyAt(i);
222 layer = mHwcLayersChangeType.valueAt(i);
223 if (layer) {
224 // deal non secure display.
225 if (!mSecure && !mHwcSecureLayers.isEmpty()) {
226 for (uint32_t j=0; j<mHwcSecureLayers.size(); j++) {
227 hwc2_layer_t secureLayerId = mHwcSecureLayers.keyAt(j);
228 HwcLayer* secureLayer = mHwcSecureLayers.valueAt(j);
229 // deal secure layers release fence and composition type on non secure display.
230 addReleaseFence(secureLayerId, secureLayer->getDuppedAcquireFence());
231 if (layerId == secureLayerId) {
232 if (layer->getCompositionType() != HWC2_COMPOSITION_DEVICE) {
233 layer->setCompositionType(HWC2_COMPOSITION_DEVICE);
234 continue;
235 }
236 }
237 }
238 }
239 if (layer->getCompositionType() == HWC2_COMPOSITION_DEVICE
240 || layer->getCompositionType() == HWC2_COMPOSITION_SOLID_COLOR) {
241 layer->setCompositionType(HWC2_COMPOSITION_CLIENT);
242 } else if (layer->getCompositionType() == HWC2_COMPOSITION_SIDEBAND) {
243 layer->setCompositionType(HWC2_COMPOSITION_DEVICE);
244 }
245 }
246 }
247
248 return HWC2_ERROR_NONE;
249}
250
251bool PhysicalDevice::createLayer(hwc2_layer_t* outLayer) {
252 HwcLayer* layer = new HwcLayer(mId);
253
254 if (layer == NULL || !layer->initialize()) {
255 ETRACE("createLayer: failed !");
256 return false;
257 }
258
259 hwc2_layer_t layerId = reinterpret_cast<hwc2_layer_t>(layer);
260 mHwcLayers.add(layerId, layer);
261 *outLayer = layerId;
262 DTRACE("::createLayer layerId (%lld), size: [%d].\n", layerId, mHwcLayers.size());
263
264 return true;
265}
266
267bool PhysicalDevice::destroyLayer(hwc2_layer_t layerId) {
268 HwcLayer* layer = mHwcLayers.valueFor(layerId);
269 DTRACE("::destroyLayer layerId %lld, size: [%d].\n", layerId, mHwcLayers.size());
270
271 if (layer == NULL) {
272 ETRACE("destroyLayer: no Hwclayer found (%d)", layerId);
273 return false;
274 }
275
276 for (int i = 0; i < 2; i++) {
277 ssize_t idx = mLayerReleaseFences[i].indexOfKey(layerId);
278 if (idx >= 0) {
279 HwcFenceControl::closeFd(mLayerReleaseFences[i].valueAt(idx));
280 mLayerReleaseFences[i].removeItemsAt(idx);
281 DTRACE("destroyLayer layer(%lld) from cur release list (%p).\n", layerId, &(mLayerReleaseFences[i]));
282 }
283 }
284
285 mHwcLayers.removeItem(layerId);
286 DEINIT_AND_DELETE_OBJ(layer);
287 return true;
288}
289
290int32_t PhysicalDevice::getActiveConfig(
291 hwc2_config_t* outConfig) {
292 Mutex::Autolock _l(mLock);
293
294 return mDisplayHdmi->getActiveConfig(outConfig);
295}
296
297int32_t PhysicalDevice::getChangedCompositionTypes(
298 uint32_t* outNumElements,
299 hwc2_layer_t* outLayers,
300 int32_t* /*hwc2_composition_t*/ outTypes) {
301 HwcLayer* layer = NULL;
302
303 // if outLayers or outTypes were NULL, the number of layers and types which would have been returned.
304 if (NULL == outLayers || NULL == outTypes) {
305 *outNumElements = mHwcLayersChangeType.size();
306 } else {
307 for (uint32_t i=0; i<mHwcLayersChangeType.size(); i++) {
308 hwc2_layer_t layerId = mHwcLayersChangeType.keyAt(i);
309 layer = mHwcLayersChangeType.valueAt(i);
310 if (layer) {
311 // deal non secure display.
312 if (!mSecure && !mHwcSecureLayers.isEmpty()) {
313 for (uint32_t j=0; j<mHwcSecureLayers.size(); j++) {
314 hwc2_layer_t secureLayerId = mHwcSecureLayers.keyAt(j);
315 if (layerId == secureLayerId) {
316 if (layer->getCompositionType() != HWC2_COMPOSITION_DEVICE) {
317 outLayers[i] = layerId;
318 outTypes[i] = HWC2_COMPOSITION_DEVICE;
319 continue;
320 }
321 }
322 }
323 }
324
325 if (layer->getCompositionType() == HWC2_COMPOSITION_DEVICE
326 || layer->getCompositionType() == HWC2_COMPOSITION_SOLID_COLOR) {
327 // change all other device type to client.
328 outLayers[i] = layerId;
329 outTypes[i] = HWC2_COMPOSITION_CLIENT;
330 continue;
331 }
332
333 // sideband stream.
334 if (layer->getCompositionType() == HWC2_COMPOSITION_SIDEBAND
335 /* && layer->getSidebandStream()*/) {
336 // TODO: we just transact SIDEBAND to OVERLAY for now;
337 DTRACE("get HWC_SIDEBAND layer, just change to overlay");
338 outLayers[i] = layerId;
339 outTypes[i] = HWC2_COMPOSITION_DEVICE;
340 continue;
341 }
342 }
343 }
344
345 if (mHwcLayersChangeType.size() > 0) {
346 DTRACE("There are %d layers type has changed.", mHwcLayersChangeType.size());
347 *outNumElements = mHwcLayersChangeType.size();
348 } else {
349 DTRACE("No layers compositon type changed.");
350 }
351 }
352
353 return HWC2_ERROR_NONE;
354}
355
356int32_t PhysicalDevice::getClientTargetSupport(
357 uint32_t width,
358 uint32_t height,
359 int32_t /*android_pixel_format_t*/ format,
360 int32_t /*android_dataspace_t*/ dataspace) {
361 framebuffer_info_t* fbInfo = mFramebufferContext->getInfo();
362
363 if (width == fbInfo->info.xres
364 && height == fbInfo->info.yres
365 && format == HAL_PIXEL_FORMAT_RGBA_8888
366 && dataspace == HAL_DATASPACE_UNKNOWN) {
367 return HWC2_ERROR_NONE;
368 }
369
370 DTRACE("fbinfo: [%d x %d], client: [%d x %d]"
371 "format: %d, dataspace: %d",
372 fbInfo->info.xres,
373 fbInfo->info.yres,
374 width, height, format, dataspace);
375
376 // TODO: ?
377 return HWC2_ERROR_UNSUPPORTED;
378}
379
380int32_t PhysicalDevice::getColorModes(
381 uint32_t* outNumModes,
382 int32_t* /*android_color_mode_t*/ outModes) {
383
384 if (NULL == outModes) {
385 *outNumModes = 1;
386 } else {
387 *outModes = HAL_COLOR_MODE_NATIVE;
388 }
389
390 return HWC2_ERROR_NONE;
391}
392
393int32_t PhysicalDevice::getDisplayAttribute(
394 hwc2_config_t config,
395 int32_t /*hwc2_attribute_t*/ attribute,
396 int32_t* outValue) {
397 Mutex::Autolock _l(mLock);
398
399 if (!mConnectorPresent) {
400 ETRACE("display %d is not connected.", mId);
401 }
402
403 int ret = mDisplayHdmi->getDisplayAttribute(config, attribute, outValue);
404 if (ret < 0)
405 return HWC2_ERROR_BAD_CONFIG;
406
407 return HWC2_ERROR_NONE;
408}
409
410int32_t PhysicalDevice::getDisplayConfigs(
411 uint32_t* outNumConfigs,
412 hwc2_config_t* outConfigs) {
413 Mutex::Autolock _l(mLock);
414
415 return mDisplayHdmi->getDisplayConfigs(outNumConfigs, outConfigs);
416}
417
418int32_t PhysicalDevice::getDisplayName(
419 uint32_t* outSize,
420 char* outName) {
421 return HWC2_ERROR_NONE;
422}
423
424int32_t PhysicalDevice::getDisplayRequests(
425 int32_t* /*hwc2_display_request_t*/ outDisplayRequests,
426 uint32_t* outNumElements,
427 hwc2_layer_t* outLayers,
428 int32_t* /*hwc2_layer_request_t*/ outLayerRequests) {
429
430 // if outLayers or outTypes were NULL, the number of layers and types which would have been returned.
431 if (NULL == outLayers || NULL == outLayerRequests) {
432 *outNumElements = mHwcLayersChangeRequest.size();
433 } else {
434 for (uint32_t i=0; i<mHwcLayersChangeRequest.size(); i++) {
435 hwc2_layer_t layerId = mHwcLayersChangeRequest.keyAt(i);
436 HwcLayer *layer = mHwcLayersChangeRequest.valueAt(i);
437 if (layer->getCompositionType() == HWC2_COMPOSITION_DEVICE) {
438 // video overlay.
439 if (layerId == mVideoOverlayLayerId) {
440 outLayers[i] = layerId;
441 outLayerRequests[i] = HWC2_LAYER_REQUEST_CLEAR_CLIENT_TARGET;
442 }
443 /* if (layer->getBufferHandle()) {
444 private_handle_t const* hnd =
445 private_handle_t::dynamicCast(layer->getBufferHandle());
446 if (hnd->flags & private_handle_t::PRIV_FLAGS_VIDEO_OVERLAY) {
447 outLayers[i] = layerId;
448 outLayerRequests[i] = HWC2_LAYER_REQUEST_CLEAR_CLIENT_TARGET;
449 continue;
450 }
451 } */
452 }
453
454 // sideband stream.
455 if ((layer->getCompositionType() == HWC2_COMPOSITION_SIDEBAND /*&& layer->getSidebandStream()*/)
456 || layer->getCompositionType() == HWC2_COMPOSITION_CURSOR) {
457 // TODO: we just transact SIDEBAND to OVERLAY for now;
458 DTRACE("get HWC_SIDEBAND layer, just change to overlay");
459 outLayers[i] = layerId;
460 outLayerRequests[i] = HWC2_LAYER_REQUEST_CLEAR_CLIENT_TARGET;
461 continue;
462 }
463 }
464
465 if (mHwcLayersChangeRequest.size() > 0) {
466 DTRACE("There are %d layer requests.", mHwcLayersChangeRequest.size());
467 *outNumElements = mHwcLayersChangeRequest.size();
468 } else {
469 DTRACE("No layer requests.");
470 }
471 }
472
473 return HWC2_ERROR_NONE;
474}
475
476int32_t PhysicalDevice::getDisplayType(
477 int32_t* /*hwc2_display_type_t*/ outType) {
478
479 *outType = HWC2_DISPLAY_TYPE_PHYSICAL;
480 return HWC2_ERROR_NONE;
481}
482
483int32_t PhysicalDevice::getDozeSupport(
484 int32_t* outSupport) {
485 return HWC2_ERROR_NONE;
486}
487
488int32_t PhysicalDevice::getHdrCapabilities(
489 uint32_t* outNumTypes,
490 int32_t* /*android_hdr_t*/ outTypes,
491 float* outMaxLuminance,
492 float* outMaxAverageLuminance,
493 float* outMinLuminance) {
494
495 Mutex::Autolock _l(mLock);
496 if (!mConnectorPresent) {
497 ETRACE("disp: %llu is not connected", mId);
498 return HWC2_ERROR_BAD_DISPLAY;
499 }
500
501 if (!mHdrCapabilities.init) {
502 ETRACE("HDRCapability not updated.");
503 }
504
505 if (NULL == outTypes) {
506 int num = 0;
507 if (mHdrCapabilities.dvSupport) num++;
508 if (mHdrCapabilities.hdrSupport) num++;
509
510 *outNumTypes = num;
511 } else {
512 if (mHdrCapabilities.dvSupport) *outTypes++ = HAL_HDR_DOLBY_VISION;
513 if (mHdrCapabilities.hdrSupport) *outTypes++ = HAL_HDR_HDR10;
514
515 *outMaxLuminance = mHdrCapabilities.maxLuminance;
516 *outMaxAverageLuminance = mHdrCapabilities.avgLuminance;
517 *outMinLuminance = mHdrCapabilities.minLuminance;
518 }
519
520 return HWC2_ERROR_NONE;
521}
522
523void PhysicalDevice::swapReleaseFence() {
524 //dumpFenceList(mHwcCurReleaseFences);
525
526 if (mHwcCurReleaseFences == NULL || mHwcPriorReleaseFences == NULL) {
527 if (mHwcCurReleaseFences) {
528 clearFenceList(mHwcPriorReleaseFences);
529 }
530
531 if (mHwcPriorReleaseFences) {
532 clearFenceList(mHwcPriorReleaseFences);
533 }
534
535 mHwcCurReleaseFences = &(mLayerReleaseFences[0]);
536 mHwcPriorReleaseFences = &(mLayerReleaseFences[1]);
537 } else {
538 KeyedVector<hwc2_layer_t, int32_t> * tmp = mHwcCurReleaseFences;
539 clearFenceList(mHwcPriorReleaseFences);
540 mHwcCurReleaseFences = mHwcPriorReleaseFences;
541 mHwcPriorReleaseFences = tmp;
542 }
543}
544
545void PhysicalDevice::addReleaseFence(hwc2_layer_t layerId, int32_t fenceFd) {
546 ssize_t idx = mHwcCurReleaseFences->indexOfKey(layerId);
547 if (idx >= 0 && idx < mHwcCurReleaseFences->size()) {
548 int32_t oldFence = mHwcCurReleaseFences->valueAt(idx);
549 String8 mergeName("hwc-release");
550 int32_t newFence = HwcFenceControl::merge(mergeName, oldFence, fenceFd);
551 mHwcCurReleaseFences->replaceValueAt(idx, newFence);
552 HwcFenceControl::closeFd(oldFence);
553 HwcFenceControl::closeFd(fenceFd);
554 DTRACE("addReleaseFence:(%d, %d) + %d -> (%d,%d)\n", idx, oldFence, fenceFd, idx, newFence);
555 dumpFenceList(mHwcCurReleaseFences);
556 } else {
557 mHwcCurReleaseFences->add(layerId, fenceFd);
558 }
559}
560
561void PhysicalDevice::clearFenceList(KeyedVector<hwc2_layer_t, int32_t> * fenceList) {
562 if (!fenceList || !fenceList->size())
563 return;
564
565 for (int i = 0; i < fenceList->size(); i++) {
566 int32_t fenceFd = fenceList->valueAt(i);
567 HwcFenceControl::closeFd(fenceFd);
568 DTRACE("clearFenceList close fd %d\n", fenceFd);
569 fenceList->replaceValueAt(i, -1);
570 }
571 fenceList->clear();
572}
573
574void PhysicalDevice::dumpFenceList(KeyedVector<hwc2_layer_t, int32_t> * fenceList) {
575 if (!fenceList || fenceList->isEmpty())
576 return;
577
578 String8 resultStr("dumpFenceList: ");
579 for (int i = 0; i < fenceList->size(); i++) {
580 hwc2_layer_t layerId = fenceList->keyAt(i);
581 int32_t fenceFd = fenceList->valueAt(i);
582 resultStr.appendFormat("(%lld, %d), ", layerId, fenceFd);
583 }
584
585 ETRACE("%s", resultStr.string());
586}
587
588int32_t PhysicalDevice::getReleaseFences(
589 uint32_t* outNumElements,
590 hwc2_layer_t* outLayers,
591 int32_t* outFences) {
592 *outNumElements = mHwcPriorReleaseFences->size();
593
594 if (outLayers && outFences) {
595 for (uint32_t i=0; i<mHwcPriorReleaseFences->size(); i++) {
596 outLayers[i] = mHwcPriorReleaseFences->keyAt(i);
597 outFences[i] = HwcFenceControl::dupFence(mHwcPriorReleaseFences->valueAt(i));
598 }
599 }
600
601 return HWC2_ERROR_NONE;
602}
603
604void PhysicalDevice::directCompose(framebuffer_info_t * fbInfo) {
605 HwcLayer* layer = NULL;
606 ssize_t idx = mHwcLayers.indexOfKey(mDirectRenderLayerId);
607 if (idx >= 0) {
608 layer = mHwcLayers.valueAt(idx);
609 if (mTargetAcquireFence > -1) {
610 ETRACE("ERROR:directCompose with mTargetAcquireFence %d\n", mTargetAcquireFence);
611 HwcFenceControl::closeFd(mTargetAcquireFence);
612 }
613
614 mTargetAcquireFence = layer->getDuppedAcquireFence();
615 mClientTargetHnd = layer->getBufferHandle();
616 DTRACE("Hit only one non video overlay layer, handle: %08" PRIxPTR ", fence: %d",
617 intptr_t(mClientTargetHnd), mTargetAcquireFence);
618
619 // fill up fb sync request struct.
620 hwc_frect_t srcCrop = layer->getSourceCrop();
621 hwc_rect_t displayFrame = layer->getDisplayFrame();
622 mFbSyncRequest.xoffset = (unsigned int)srcCrop.left;
623 mFbSyncRequest.yoffset = (unsigned int)srcCrop.top;
624 mFbSyncRequest.width = (unsigned int)(srcCrop.right - srcCrop.left);
625 mFbSyncRequest.height = (unsigned int)(srcCrop.bottom - srcCrop.top);
626 mFbSyncRequest.dst_x = displayFrame.left;
627 mFbSyncRequest.dst_y = displayFrame.top;
628 mFbSyncRequest.dst_w = displayFrame.right - displayFrame.left;
629 mFbSyncRequest.dst_h = displayFrame.bottom - displayFrame.top;
630 return;
631 }
632
633 ETRACE("Didn't find direct compose layer!");
634}
635
636#ifdef ENABLE_AML_GE2D_COMPOSER
637void PhysicalDevice::ge2dCompose(framebuffer_info_t * fbInfo, bool hasVideoOverlay) {
638 if (mGE2DRenderSortedLayerIds.size() > 0) {
639 DTRACE("GE2D compose mFbSlot: %d", mFbSlot);
640 if (hasVideoOverlay) {
641 if (mGE2DClearVideoRegionCount < 3) {
642 mComposer->setVideoOverlayLayerId(mVideoOverlayLayerId);
643 }
644 }
645 if (mTargetAcquireFence > -1) {
646 ETRACE("ERROR:GE2D compose with mTargetAcquireFence %d\n", mTargetAcquireFence);
647 HwcFenceControl::closeFd(mTargetAcquireFence);
648 }
649 mTargetAcquireFence = mComposer->startCompose(mGE2DRenderSortedLayerIds, &mFbSlot, mGE2DComposeFrameCount);
650 for (uint32_t i=0; i<mGE2DRenderSortedLayerIds.size(); i++) {
651 addReleaseFence(mGE2DRenderSortedLayerIds.itemAt(i), HwcFenceControl::dupFence(mTargetAcquireFence));
652 }
653 // HwcFenceControl::traceFenceInfo(mTargetAcquireFence);
654 // dumpLayers(mGE2DRenderSortedLayerIds);
655 if (mGE2DComposeFrameCount < 3) {
656 mGE2DComposeFrameCount++;
657 }
658 mClientTargetHnd = mComposer->getBufHnd();
659 fbInfo->yOffset = mFbSlot;
660 return;
661 }
662
663 ETRACE("Didn't find ge2d compose layers!");
664}
665#endif
666
667int32_t PhysicalDevice::postFramebuffer(int32_t* outRetireFence, bool hasVideoOverlay) {
668 bool bUseHwcPost = true;
669
670 framebuffer_info_t fbInfo = *(mFramebufferContext->getInfo());
671 bool cursorShow = false;
672 cursorShow = updateCursorBuffer();
673
674 if (mRenderMode == GLES_COMPOSE_MODE) {
675 //if no layers to compose, post blank op to osd.
676 if (mPreviousRenderMode != GLES_COMPOSE_MODE && mHwcGlesLayers.size() == 0) {
677 mClientTargetHnd = NULL;
678 }
679 } else if (mRenderMode == DIRECT_COMPOSE_MODE) { // if only one layer exists, let hwc do her work.
680 directCompose(&fbInfo);
681 }
682#ifdef ENABLE_AML_GE2D_COMPOSER
683 else if (mRenderMode == GE2D_COMPOSE_MODE) {
684 ge2dCompose(&fbInfo, hasVideoOverlay);
685 }
686#endif
687 mFbSyncRequest.type = mRenderMode;
688
689 if (!mClientTargetHnd || private_handle_t::validate(mClientTargetHnd) < 0 || mPowerMode == HWC2_POWER_MODE_OFF) {
690 DTRACE("Post blank to screen, mClientTargetHnd(%p, %d), mTargetAcquireFence(%d)",
691 mClientTargetHnd, private_handle_t::validate(mClientTargetHnd), mTargetAcquireFence);
692 *outRetireFence = HwcFenceControl::merge(String8("ScreenBlank"), mPriorFrameRetireFence, mPriorFrameRetireFence);
693 HwcFenceControl::closeFd(mTargetAcquireFence);
694 mTargetAcquireFence = -1;
695 HwcFenceControl::closeFd(mPriorFrameRetireFence);
696 mPriorFrameRetireFence = -1;
697 //for nothing to display, post blank to osd which will signal the last retire fence.
698 mFbSyncRequest.type = DIRECT_COMPOSE_MODE;
699 mFbSyncRequest.op |= OSD_BLANK_OP_BIT;
700 mFramebufferContext->setStatus(true);
701 mPriorFrameRetireFence = hwc_fb_post_with_fence_locked(&fbInfo, &mFbSyncRequest, NULL);
702 } else {
703 *outRetireFence = HwcFenceControl::dupFence(mPriorFrameRetireFence);
704 if (*outRetireFence >= 0) {
705 DTRACE("Get prior frame's retire fence %d", *outRetireFence);
706 } else {
707 ETRACE("No valid prior frame's retire returned. %d ", *outRetireFence);
708 // -1 means no fence, less than -1 is some error
709 *outRetireFence = -1;
710 }
711 HwcFenceControl::closeFd(mPriorFrameRetireFence);
712 mPriorFrameRetireFence = -1;
713
714 bool needBlankFb0 = false;
715 uint32_t layerNum = mHwcLayers.size();
716 if (hasVideoOverlay
717 && (layerNum == 1
718 || (layerNum == 2
719 && cursorShow))) {
720 needBlankFb0 = true;
721 }
722
723 //close uboot logo, if bootanim begin to show
724 if (mFirstPostFb) {
725 mFirstPostFb = false;
726
727 Utils::setSysfsStr(DISPLAY_LOGO_INDEX, "-1");
728 Utils::setSysfsStr(DISPLAY_FB0_FREESCALE_SWTICH, "0x10001");
729 setOsdMouse();
730 }
731
732 // real post framebuffer here.
733 DTRACE("render type: %d", mFbSyncRequest.type);
734
735 if (!bUseHwcPost) {
736 setOSD0Blank(needBlankFb0);
737 mPriorFrameRetireFence = fb_post_with_fence_locked(&fbInfo, mClientTargetHnd, mTargetAcquireFence);
738 } else {
739 // bit 0 is osd blank flag.
740 if (needBlankFb0) {
741 mFbSyncRequest.op |= OSD_BLANK_OP_BIT;
742 } else {
743 mFbSyncRequest.op &= ~(OSD_BLANK_OP_BIT);
744 }
745 mFramebufferContext->setStatus(needBlankFb0);
746 // acquire fence.
747 mFbSyncRequest.in_fen_fd = mTargetAcquireFence;
748 mPriorFrameRetireFence = hwc_fb_post_with_fence_locked(&fbInfo, &mFbSyncRequest, mClientTargetHnd);
749 }
750 mTargetAcquireFence = -1;
751
752 if (mRenderMode == GE2D_COMPOSE_MODE) {
753 mComposer->mergeRetireFence(mFbSlot, HwcFenceControl::dupFence(mPriorFrameRetireFence));
754 } else {
755 if (mComposer && mGE2DComposeFrameCount != 0) {
756 mComposer->removeRetireFence(mFbSlot);
757 }
758
759 if (mRenderMode == DIRECT_COMPOSE_MODE) {
760 addReleaseFence(mDirectRenderLayerId, HwcFenceControl::dupFence(mPriorFrameRetireFence));
761 }
762 }
763
764 // finally we need to update cursor's blank status.
765 setOSD1Blank(cursorShow);
766 }
767
768 if (mRenderMode != GE2D_COMPOSE_MODE) {
769 mGE2DComposeFrameCount = 0;
770 }
771
772 return HWC2_ERROR_NONE;
773}
774
775// deal physical display's client target layer
776bool PhysicalDevice::updateCursorBuffer() {
777 framebuffer_info_t* cbInfo = mCursorContext->getInfo();
778 HwcLayer* layer = NULL;
779 void *cbuffer;
780
781 for (uint32_t i=0; i<mHwcLayers.size(); i++) {
782 hwc2_layer_t layerId = mHwcLayers.keyAt(i);
783 layer = mHwcLayers.valueAt(i);
784 if (layer && layer->getCompositionType()== HWC2_COMPOSITION_CURSOR) {
785 private_handle_t *hnd = private_handle_t::dynamicCast(layer->getBufferHandle());
786 if (!hnd) {
787 ETRACE("invalid cursor layer handle.");
788 break;
789 }
790 DTRACE("This is a Sprite, hnd->width is %d(%d), hnd->height is %d",
791 hnd->width, hnd->stride, hnd->height);
792 if (cbInfo->info.xres != (uint32_t)hnd->stride || cbInfo->info.yres != (uint32_t)hnd->height) {
793 DTRACE("disp: %d cursor need to redrew", mId);
794 update_cursor_buffer_locked(cbInfo, hnd->stride, hnd->height);
795 cbuffer = mmap(NULL, hnd->size, PROT_READ|PROT_WRITE, MAP_SHARED, cbInfo->fd, 0);
796 if (cbuffer != MAP_FAILED) {
797 memset(cbuffer, 1, hnd->size);
798
799 uint32_t irow = 0;
800 char* cpyDst = (char*)cbuffer;
801 char* cpySrc = (char*)hnd->base;
802 for (irow = 0; irow < hnd->height; irow++) {
803 memcpy(cpyDst, cpySrc, 4 * hnd->width);
804 cpyDst += 4 * hnd->stride;
805 cpySrc += 4 * hnd->stride;
806 }
807 munmap(cbuffer, hnd->size);
808 DTRACE("setCursor ok");
809 } else {
810 ETRACE("Cursor display buffer mmap fail!");
811 }
812 }
813 return true;
814 }
815 }
816 return false;
817}
818
819void PhysicalDevice::setOsdMouse()
820{
821 bool ret = true;
822 char cur_mode[MODE_LEN] = {0};
823 Utils::getSysfsStr(SYSFS_DISPLAY_MODE, cur_mode);
824 DTRACE("set osd mouse mode: %s", cur_mode);
825 int position[4] = { 0, 0, 0, 0 };//x,y,w,h
826 getOsdPosition(cur_mode, position);
827 setOsdMouse(position[0], position[1], position[2], position[3], cur_mode);
828}
829
830void PhysicalDevice::setOsdMouse(int x, int y, int w, int h, const char* cur_mode)
831{
832 DTRACE("set osd mouse x:%d y:%d w:%d h:%d", x, y, w, h);
833 const char* displaySize = "1920 1080";
834 int display_w, display_h;
835 if (!strncmp(mDefaultMode, "720", 3)) {
836 displaySize = "1280 720";
837 } else if (!strncmp(mDefaultMode, "1080", 4)) {
838 displaySize = "1920 1080";
839 } else if (!strncmp(mDefaultMode, "4k2k", 4)) {
840 displaySize = "3840 2160";
841 }
842
843 if (!strcmp(cur_mode, MODE_480I) || !strcmp(cur_mode, MODE_576I) ||
844 !strcmp(cur_mode, MODE_480CVBS) || !strcmp(cur_mode, MODE_576CVBS) ||
845 !strcmp(cur_mode, MODE_1080I50HZ) || !strcmp(cur_mode, MODE_1080I)) {
846 y /= 2;
847 h /= 2;
848 }
849
850 char axis[512] = {0};
851 sprintf(axis, "%d %d %s %d %d 18 18", x, y, displaySize, x, y);
852 Utils::setSysfsStr(SYSFS_DISPLAY_AXIS, axis);
853
854 sprintf(axis, "%s %d %d", displaySize, w, h);
855 sscanf(displaySize,"%d %d",&display_w,&display_h);
856 Utils::setSysfsStr(DISPLAY_FB1_SCALE_AXIS, axis);
857 if ((display_w != w) || (display_h != h)) {
858 Utils::setSysfsStr(DISPLAY_FB1_SCALE, "0x10001");
859 } else {
860 Utils::setSysfsStr(DISPLAY_FB1_SCALE, "0");
861 }
862}
863
864int PhysicalDevice::getOsdPosition(const char* curMode, int *position) {
865 auto scs = getSystemControlService();
866 if (scs == NULL) {
867 ETRACE("syscontrol::getOsdPosition FAIL.");
868 return FAILED_TRANSACTION;
869 }
870 scs->getPosition(curMode, [&position](const Result &ret,
871 int left, int top, int width, int height) {
872 if (ret == Result::OK) {
873 position[0] = left;
874 position[1] = top;
875 position[2] = width;
876 position[3] = height;
877 }
878 });
879 return NO_ERROR;
880}
881
882int32_t PhysicalDevice::setOSD1Blank(bool cursorShow) {
883 framebuffer_info_t* cbInfo = mCursorContext->getInfo();
884
885 if (cbInfo->fd > 0 && cursorShow != mCursorContext->getStatus()) {
886 mCursorContext->setStatus(cursorShow);
887 DTRACE("UPDATE FB1 status to %d", !cursorShow);
888 ioctl(cbInfo->fd, FBIOBLANK, !cursorShow);
889 }
890
891 return HWC2_ERROR_NONE;
892}
893
894// TODO: need add fence wait.
895int32_t PhysicalDevice::setOSD0Blank(bool blank) {
896 framebuffer_info_t* fbInfo = mFramebufferContext->getInfo();
897
898 if (fbInfo->fd > 0 && blank != mFramebufferContext->getStatus()) {
899 mFramebufferContext->setStatus(blank);
900 DTRACE("UPDATE FB0 status to %d", blank);
901 ioctl(fbInfo->fd, FBIOBLANK, blank);
902 }
903
904 return HWC2_ERROR_NONE;
905}
906
907int32_t PhysicalDevice::presentDisplay(
908 int32_t* outRetireFence) {
909 int32_t err = HWC2_ERROR_NONE;
910 HwcLayer* layer = NULL;
911 bool hasVideoOverlay = false;
912
913 if (mIsValidated) {
914 // TODO: need improve the way to set video axis.
915 bool bPresent = true;
916 if (mHwcSecureLayers.indexOfKey(mVideoOverlayLayerId) >= 0) {
917 bPresent = false;
918 }
919
920 ssize_t index = mHwcLayers.indexOfKey(mVideoOverlayLayerId);
921 if (index >= 0) {
922 layer = mHwcLayers.valueFor(mVideoOverlayLayerId);
923 if (layer != NULL) {
924 layer->presentOverlay(bPresent);
925 hasVideoOverlay = true;
926 if (mGE2DClearVideoRegionCount < 3) {
927 mGE2DClearVideoRegionCount++;
928 }
929 }
930 } else {
931 mGE2DClearVideoRegionCount = 0;
932 }
933 err = postFramebuffer(outRetireFence, hasVideoOverlay);
934 } else { // display not validate yet.
935 err = HWC2_ERROR_NOT_VALIDATED;
936 }
937
938 finishCompose();
939 return err;
940}
941
942int32_t PhysicalDevice::setActiveConfig(
943 hwc2_config_t config) {
944 Mutex::Autolock _l(mLock);
945
946 int32_t err = mDisplayHdmi->setActiveConfig(config);
947 if (err == HWC2_ERROR_NONE) {
948 updateActiveDisplayAttribute();
949 }
950
951 return err;
952}
953
954int32_t PhysicalDevice::setClientTarget(
955 buffer_handle_t target,
956 int32_t acquireFence,
957 int32_t /*android_dataspace_t*/ dataspace,
958 hwc_region_t damage) {
959
960 if (target && private_handle_t::validate(target) < 0) {
961 return HWC2_ERROR_BAD_PARAMETER;
962 }
963
964 if (NULL != target) {
965 mClientTargetHnd = target;
966 mClientTargetDamageRegion = damage;
967 mTargetAcquireFence = acquireFence;
968 DTRACE("setClientTarget %p, %d", target, acquireFence);
969 // TODO: HWC2_ERROR_BAD_PARAMETER && dataspace && damage.
970 } else {
971 DTRACE("client target is null!, no need to update this frame.");
972 }
973
974 return HWC2_ERROR_NONE;
975}
976
977int32_t PhysicalDevice::setColorMode(
978 int32_t /*android_color_mode_t*/ mode) {
979 return HWC2_ERROR_NONE;
980}
981
982int32_t PhysicalDevice::setColorTransform(
983 const float* matrix,
984 int32_t /*android_color_transform_t*/ hint) {
985 return HWC2_ERROR_NONE;
986}
987
988int32_t PhysicalDevice::setPowerMode(
989 int32_t /*hwc2_power_mode_t*/ mode){
990
991 mPowerMode = mode;
992 return HWC2_ERROR_NONE;
993}
994
995bool PhysicalDevice::vsyncControl(bool enabled) {
996 RETURN_FALSE_IF_NOT_INIT();
997
998 ATRACE("disp = %d, enabled = %d", mId, enabled);
999 return mVsyncObserver->control(enabled);
1000}
1001
1002void PhysicalDevice::dumpLayers(Vector < hwc2_layer_t > layerIds) {
1003 for (uint32_t x=0; x<layerIds.size(); x++) {
1004 HwcLayer* layer = getLayerById(layerIds.itemAt(x));
1005 static char const* compositionTypeName[] = {
1006 "UNKNOWN",
1007 "GLES",
1008 "HWC",
1009 "SOLID",
1010 "HWC_CURSOR",
1011 "SIDEBAND"};
1012 ETRACE(" %11s | %12" PRIxPTR " | %10d | %02x | %1.2f | %02x | %04x |%7.1f,%7.1f,%7.1f,%7.1f |%5d,%5d,%5d,%5d \n",
1013 compositionTypeName[layer->getCompositionType()],
1014 intptr_t(layer->getBufferHandle()), layer->getZ(), layer->getDataspace(),
1015 layer->getPlaneAlpha(), layer->getTransform(), layer->getBlendMode(),
1016 layer->getSourceCrop().left, layer->getSourceCrop().top, layer->getSourceCrop().right, layer->getSourceCrop().bottom,
1017 layer->getDisplayFrame().left, layer->getDisplayFrame().top, layer->getDisplayFrame().right, layer->getDisplayFrame().bottom);
1018 }
1019}
1020
1021void PhysicalDevice::dumpLayers(KeyedVector<hwc2_layer_t, HwcLayer*> layers) {
1022 for (uint32_t x=0; x<layers.size(); x++) {
1023 HwcLayer* layer = layers.valueAt(x);
1024 static char const* compositionTypeName[] = {
1025 "UNKNOWN",
1026 "GLES",
1027 "HWC",
1028 "SOLID",
1029 "HWC_CURSOR",
1030 "SIDEBAND"};
1031 ETRACE(" %11s | %12" PRIxPTR " | %10d | %02x | %1.2f | %02x | %04x |%7.1f,%7.1f,%7.1f,%7.1f |%5d,%5d,%5d,%5d \n",
1032 compositionTypeName[layer->getCompositionType()],
1033 intptr_t(layer->getBufferHandle()), layer->getZ(), layer->getDataspace(),
1034 layer->getPlaneAlpha(), layer->getTransform(), layer->getBlendMode(),
1035 layer->getSourceCrop().left, layer->getSourceCrop().top, layer->getSourceCrop().right, layer->getSourceCrop().bottom,
1036 layer->getDisplayFrame().left, layer->getDisplayFrame().top, layer->getDisplayFrame().right, layer->getDisplayFrame().bottom);
1037 }
1038}
1039
1040bool PhysicalDevice::layersStateCheck(int32_t renderMode,
1041 KeyedVector<hwc2_layer_t, HwcLayer*> & composeLayers) {
1042 bool ret = false;
1043 uint32_t layerNum = composeLayers.size();
1044 hwc_frect_t sourceCrop[HWC2_MAX_LAYERS];
1045 HwcLayer* layer[HWC2_MAX_LAYERS] = { NULL };
1046 private_handle_t const* hnd[HWC2_MAX_LAYERS] = { NULL };
1047 hwc_rect_t displayFrame[HWC2_MAX_LAYERS];
1048
1049 for (int32_t i=0; i<layerNum; i++) {
1050 layer[i] = composeLayers.valueAt(i);
1051 sourceCrop[i] = layer[i]->getSourceCrop();
1052 displayFrame[i] = layer[i]->getDisplayFrame();
1053 hnd[i] = private_handle_t::dynamicCast(layer[i]->getBufferHandle());
1054 if (hnd[i] == NULL) return false; // no buffer to process.
1055 if (hnd[i]->share_fd == -1) return false; // no buffer to process.
1056 if ((sourceCrop[i].right - sourceCrop[i].left > HWC2_HW_COMPOSE_WIDTH_MAX) ||
1057 (sourceCrop[i].bottom - sourceCrop[i].top > HWC2_HW_COMPOSE_HEIGHT_MAX)) {
1058 return false;
1059 }
1060 DTRACE("layer[%d] zorder: %d, blend: %d, PlaneAlpha: %f, "
1061 "mColor: [%d, %d, %d, %d], mDataSpace: %d, format hnd[%d]: %x",
1062 i, layer[i]->getZ(), layer[i]->getBlendMode(), layer[i]->getPlaneAlpha(),
1063 layer[i]->getColor().r, layer[i]->getColor().g, layer[i]->getColor().b,
1064 layer[i]->getColor().a, layer[i]->getDataspace(), i, hnd[i]->format);
1065 }
1066
1067 if (renderMode == DIRECT_COMPOSE_MODE) {
1068 switch (hnd[0]->format) {
1069 case HAL_PIXEL_FORMAT_RGBA_8888:
1070 case HAL_PIXEL_FORMAT_RGBX_8888:
1071 case HAL_PIXEL_FORMAT_RGB_888:
1072 case HAL_PIXEL_FORMAT_RGB_565:
1073 case HAL_PIXEL_FORMAT_BGRA_8888:
1074 DTRACE("Layer format match direct composer.");
1075 ret = true;
1076 break;
1077 default:
1078 DTRACE("Layer format not support by direct compose");
1079 return false;
1080 break;
1081 }
1082 if (layer[0]->getTransform() != 0) {
1083 //DTRACE("Direct composer can NOT support rotation now.");
1084 return false;
1085 }
1086 }
1087#ifdef ENABLE_AML_GE2D_COMPOSER
1088 else if (renderMode == GE2D_COMPOSE_MODE) {
1089 bool yuv420Sp = false;
1090 for (int32_t i=0; i<layerNum; i++) {
1091 switch (hnd[i]->format) {
1092 case HAL_PIXEL_FORMAT_YCrCb_420_SP:
1093 yuv420Sp = true;
1094 case HAL_PIXEL_FORMAT_RGBA_8888:
1095 case HAL_PIXEL_FORMAT_RGBX_8888:
1096 case HAL_PIXEL_FORMAT_RGB_888:
1097 case HAL_PIXEL_FORMAT_RGB_565:
1098 case HAL_PIXEL_FORMAT_BGRA_8888:
1099 case HAL_PIXEL_FORMAT_YV12:
1100 case HAL_PIXEL_FORMAT_Y8:
1101 case HAL_PIXEL_FORMAT_YCbCr_422_SP:
1102 case HAL_PIXEL_FORMAT_YCbCr_422_I:
1103 DTRACE("Layer format match ge2d composer.");
1104 ret = true;
1105 break;
1106 default:
1107 DTRACE("Layer format not support by ge2d");
1108 return false;
1109 break;
1110 }
1111 if (layer[i]->havePlaneAlpha()
1112 || layer[i]->haveColor()
1113 || layer[i]->haveDataspace()
1114 || (layer[i]->isBlended()
1115 && layer[i]->isScaled())) {
1116 DTRACE("ge2d compose can not process!");
1117 return false;
1118 }
1119 }
1120#if 0
1121 if (yuv420Sp && HWC2_TWO_LAYERS == layerNum) {
1122 if (Utils::compareRect(sourceCrop[0], sourceCrop[1])
1123 && Utils::compareRect(sourceCrop[0], displayFrame[0])
1124 && Utils::compareRect(sourceCrop[1], displayFrame[1])) {
1125 DTRACE("2 layers is same size and have yuv420sp format ge2d compose can not process!");
1126 return false;
1127 }
1128 }
1129#endif
1130 if (HWC2_TWO_LAYERS == layerNum
1131 && (layer[0]->isScaled() || layer[1]->isScaled())) {
1132 DTRACE("when 2 layer's size is difference, ge2d compose can not process!");
1133 return false;
1134 }
1135 }
1136#endif
1137
1138 return ret;
1139}
1140
1141/*************************************************************
1142 * For direct framebuffer composer:
1143 * 1) only support one layer.
1144 * 2) layer format: rgba, rgbx,rgb565,bgra;
1145 * 3) layer no rotation.
1146
1147 * For ge2d composer:
1148 * 1) support layer format that direct composer can't support.
1149 * 2) support 2 layers blending.
1150 * 3) support scale and rotation etc.
1151**************************************************************/
1152int32_t PhysicalDevice::composersFilter(
1153 KeyedVector<hwc2_layer_t, HwcLayer*> & composeLayers) {
1154
1155 // direct Composer.
1156 if (composeLayers.size() == HWC2_ONE_LAYER) {
1157 // if only one layer exists, do direct framebuffer composer.
1158 bool directCompose = layersStateCheck(DIRECT_COMPOSE_MODE, composeLayers);
1159 if (directCompose) {
1160 if (mDirectComposeFrameCount >= 3) {
1161 hwc2_layer_t layerGlesLayerId = composeLayers.keyAt(0);
1162 composeLayers.clear();
1163 mDirectRenderLayerId = layerGlesLayerId;
1164 return DIRECT_COMPOSE_MODE;
1165 }
1166 mDirectComposeFrameCount++;
1167 return GLES_COMPOSE_MODE;
1168 }
1169 }
1170
1171#ifdef ENABLE_AML_GE2D_COMPOSER
1172 // if direct composer can't work, try this.
1173 if (composeLayers.size() > HWC2_NO_LAYER
1174 && composeLayers.size() < HWC2_MAX_LAYERS) {
1175 bool ge2dCompose = layersStateCheck(GE2D_COMPOSE_MODE, composeLayers);
1176 if (!ge2dCompose) return GLES_COMPOSE_MODE;
1177 mGE2DRenderSortedLayerIds.clear();
1178 for (uint32_t i=0; i<composeLayers.size(); i++) {
1179 hwc2_layer_t layerGlesLayerId = composeLayers.keyAt(i);
1180 HwcLayer* layer = getLayerById(layerGlesLayerId);
1181 if (0 == i) {
1182 mGE2DRenderSortedLayerIds.push_front(layerGlesLayerId);
1183 continue;
1184 }
1185 for (uint32_t j=0; j<i; j++) {
1186 HwcLayer* layer1 = getLayerById(mGE2DRenderSortedLayerIds.itemAt(j));
1187 HwcLayer* layer2 = getLayerById(layerGlesLayerId);
1188 if (layer1 != NULL && layer2 != NULL) {
1189 uint32_t z1 = layer1->getZ();
1190 uint32_t z2 = layer2->getZ();
1191 if (layer1->getZ() > layer2->getZ()) {
1192 mGE2DRenderSortedLayerIds.insertAt(layerGlesLayerId, j, 1);
1193 break;
1194 }
1195 if (j == i-1) mGE2DRenderSortedLayerIds.push_back(layerGlesLayerId);
1196 } else {
1197 ETRACE("Layer1 or Layer2 is NULL!!!");
1198 }
1199 }
1200 }
1201
1202 // Vector < hwc2_layer_t > layerIds;
1203 if (!mComposer) {
1204 // create ge2d composer...
1205 mComposer = mControlFactory->createComposer(*this);
1206 if (!mComposer || !mComposer->initialize(mFramebufferContext->getInfo())) {
1207 DEINIT_AND_DELETE_OBJ(mComposer);
1208 return GLES_COMPOSE_MODE;
1209 }
1210 }
1211 composeLayers.clear();
1212 return GE2D_COMPOSE_MODE;
1213 }
1214#endif
1215
1216 return GLES_COMPOSE_MODE;
1217}
1218
1219bool PhysicalDevice::calReverseScale() {
1220 static float fb_w = 1920; // Query activeConfig for FB size?
1221 static float fb_h = 1080; // Query activeConfig for FB size?
1222
1223 mReverseScaleX = mReverseScaleY = 0.0f;
1224 if (fb_w <= 0.01f || fb_h <= 0.01f)
1225 return false;
1226
1227 float display_w, display_h;
1228 hwc2_config_t config;
1229 if (HWC2_ERROR_NONE != mDisplayHdmi->getRealActiveConfig(&config))
1230 return false;
1231
1232 int32_t tmpSize = 0.0f;
1233 if ( mDisplayHdmi->getDisplayAttribute(config,
1234 HWC2_ATTRIBUTE_WIDTH, &tmpSize) != NO_ERROR)
1235 return false;
1236 display_w = tmpSize;
1237 if ( mDisplayHdmi->getDisplayAttribute(config,
1238 HWC2_ATTRIBUTE_HEIGHT, &tmpSize) != NO_ERROR)
1239 return false;
1240 display_h = tmpSize;
1241
1242 if (display_w <= 0.01f || display_h <= 0.01f)
1243 return false;
1244
1245 mReverseScaleX = fb_w / display_w;
1246 mReverseScaleY = fb_h /display_h;
1247 return false;
1248}
1249
1250int32_t PhysicalDevice::preValidate() {
1251 bool bScale = (mReverseScaleX >= 0.01f && mReverseScaleX >= 0.01f) ? true : false;
1252 HwcLayer* layer = NULL;
1253 //find out video layer first.
1254 for (uint32_t i=0; i<mHwcLayers.size(); i++) {
1255 hwc2_layer_t layerId = mHwcLayers.keyAt(i);
1256 layer = mHwcLayers.valueAt(i);
1257 if (!layer) {
1258 ETRACE("Meet empty layer, id(%lld)", layerId);
1259 continue;
1260 }
1261
1262 if (bScale && (layer->getDisplayFrame().right >= 3800))
1263 layer->reverseScaledFrame(mReverseScaleX, mReverseScaleY);
1264
1265 private_handle_t const* hnd = private_handle_t::dynamicCast(layer->getBufferHandle());
1266 if (hnd && !((hnd->flags & private_handle_t::PRIV_FLAGS_CONTINUOUS_BUF)
1267 || (hnd->flags & private_handle_t::PRIV_FLAGS_VIDEO_OVERLAY))) {
1268 mIsContinuousBuf = false;
1269 }
1270
1271 if ((hnd && (hnd->flags & private_handle_t::PRIV_FLAGS_VIDEO_OVERLAY) &&
1272 (layer->getCompositionType() == HWC2_COMPOSITION_DEVICE)) ||
1273 (layer->getCompositionType() == HWC2_COMPOSITION_SIDEBAND
1274 /* && layer->getSidebandStream()*/)) {
1275 if (mVideoOverlayLayerId != 0) {
1276 ETRACE("ERROR: Find two video layer, should never get here !!");
1277 }
1278 mVideoOverlayLayerId = layerId;
1279 }
1280 }
1281
1282 return HWC2_ERROR_NONE;
1283}
1284
1285int32_t PhysicalDevice::beginCompose() {
1286 swapReleaseFence();
1287 // reset layer changed or requested size to zero.
1288 mHwcLayersChangeType.clear();
1289 mHwcLayersChangeRequest.clear();
1290 mHwcGlesLayers.clear();
1291 // deal non secure display device.
1292 mHwcSecureLayers.clear();
1293
1294 memset(&mFbSyncRequest, 0, sizeof(mFbSyncRequest));
1295 mFbSyncRequest.in_fen_fd = -1;
1296
1297 mVideoOverlayLayerId = 0;
1298 mIsContinuousBuf = true;
1299 mIsValidated = false;
1300 mRenderMode = GLES_COMPOSE_MODE;
1301
1302 return HWC2_ERROR_NONE;
1303}
1304
1305int32_t PhysicalDevice::finishCompose() {
1306 HwcLayer* layer = NULL;
1307 // reset layers' acquire fence.
1308 for (uint32_t i=0; i<mHwcLayers.size(); i++) {
1309 hwc2_layer_t layerId = mHwcLayers.keyAt(i);
1310 layer = mHwcLayers.valueAt(i);
1311 if (layer != NULL) {
1312 layer->resetAcquireFence();
1313 }
1314 }
1315
1316 mClientTargetHnd = NULL;
1317 mPreviousRenderMode = mRenderMode;
1318 return HWC2_ERROR_NONE;
1319}
1320
1321int32_t PhysicalDevice::validateDisplay(uint32_t* outNumTypes,
1322 uint32_t* outNumRequests) {
1323 HwcLayer* layer = NULL, *videoLayer = NULL;
1324 hwc_rect_t videoRect;
1325 KeyedVector<hwc2_layer_t, HwcLayer*> composeLayers;
1326 composeLayers.clear();
1327
1328 beginCompose();
1329
1330 if (preValidate() != HWC2_ERROR_NONE) {
1331 return HWC2_ERROR_BAD_LAYER;
1332 }
1333
1334 if (mVideoOverlayLayerId) {
1335 videoLayer = mHwcLayers.valueFor(mVideoOverlayLayerId);
1336 videoRect = videoLayer->getDisplayFrame();
1337 }
1338
1339 for (uint32_t i=0; i<mHwcLayers.size(); i++) {
1340 int overlapType = Utils::OVERLAP_EMPTY;
1341 hwc2_layer_t layerId = mHwcLayers.keyAt(i);
1342 layer = mHwcLayers.valueAt(i);
1343 if (!layer)
1344 continue;
1345
1346 private_handle_t const* hnd = private_handle_t::dynamicCast(layer->getBufferHandle());
1347
1348#ifdef HWC_SUPPORT_SECURE_LAYER
1349 // secure or protected layer.
1350 if (!mSecure && hnd && (hnd->flags & private_handle_t::PRIV_FLAGS_SECURE_PROTECTED)) {
1351 DTRACE("layer's secure or protected buffer flag is set! usage (%x)", hnd->flags);
1352 if (layer->getCompositionType() != HWC2_COMPOSITION_DEVICE) {
1353 mHwcLayersChangeType.add(layerId, layer);
1354 }
1355 mHwcSecureLayers.add(layerId, layer);
1356 continue;
1357 }
1358#endif
1359 if (hnd && hnd->flags & private_handle_t::PRIV_FLAGS_VIDEO_OMX) {
1360 set_omx_pts((char*)hnd->base, &mOmxVideoHandle);
1361 }
1362
1363 if (videoLayer && (layer->getZ() < videoLayer->getZ())) {
1364 DTRACE("Layer covered by video layer.");
1365 hwc_rect_t layerRect = layer->getDisplayFrame();
1366 overlapType = Utils::rectOverlap(layerRect, videoRect);
1367 }
1368
1369 switch (layer->getCompositionType()) {
1370 case HWC2_COMPOSITION_CLIENT:
1371 mHwcGlesLayers.add(layerId, layer);
1372 DTRACE("Meet a client layer!");
1373 break;
1374 case HWC2_COMPOSITION_DEVICE:
1375 if (layerId == mVideoOverlayLayerId) {
1376 mHwcLayersChangeRequest.add(layerId, layer);
1377 } else {
1378 composeLayers.add(layerId, layer);
1379 }
1380 break;
1381 case HWC2_COMPOSITION_SOLID_COLOR:
1382 if (overlapType != Utils::OVERLAP_FULL) {
1383 mHwcGlesLayers.add(layerId, layer);
1384 mHwcLayersChangeType.add(layerId, layer);
1385 }
1386 break;
1387 case HWC2_COMPOSITION_CURSOR:
1388 DTRACE("This is a Cursor layer!");
1389 mHwcLayersChangeRequest.add(layerId, layer);
1390 break;
1391 case HWC2_COMPOSITION_SIDEBAND:
1392 if (layerId == mVideoOverlayLayerId) {
1393 DTRACE("get HWC_SIDEBAND layer, just change to overlay");
1394 mHwcLayersChangeRequest.add(layerId, layer);
1395 mHwcLayersChangeType.add(layerId, layer);
1396 } else {
1397 ETRACE("SIDEBAND not handled.");
1398 }
1399 break;
1400 default:
1401 ETRACE("get layer of unknown composition type (%d)", layer->getCompositionType());
1402 break;
1403 }
1404 }
1405
1406 bool noDevComp = Utils::checkBoolProp("sys.sf.debug.nohwc");
1407#ifndef USE_CONTINOUS_BUFFER_COMPOSER
1408 DTRACE("No continous buffer composer!");
1409 noDevComp = true;
1410 mIsContinuousBuf = false;
1411#endif
1412
1413 if (mHwcLayers.size() == 0) {
1414 mIsContinuousBuf = false;
1415 }
1416
1417 // dumpLayers(mHwcLayers);
1418 if (mIsContinuousBuf && !noDevComp && (mHwcGlesLayers.size() == 0)) {
1419 mRenderMode = composersFilter(composeLayers);
1420 } else {
1421 mDirectComposeFrameCount = 0;
1422 }
1423
1424 // DEVICE_COMPOSE layers set to CLIENT_COMPOSE layers.
1425 for (int i=0; i<composeLayers.size(); i++) {
1426 mHwcLayersChangeType.add(composeLayers.keyAt(i), composeLayers.valueAt(i));
1427 mHwcGlesLayers.add(composeLayers.keyAt(i), composeLayers.valueAt(i));
1428 }
1429
1430 if (mHwcLayersChangeRequest.size() > 0) {
1431 DTRACE("There are %d layer requests.", mHwcLayersChangeRequest.size());
1432 *outNumRequests = mHwcLayersChangeRequest.size();
1433 }
1434
1435 mIsValidated = true;
1436
1437 if (mHwcLayersChangeType.size() > 0) {
1438 DTRACE("there are %d layer types has changed.", mHwcLayersChangeType.size());
1439 *outNumTypes = mHwcLayersChangeType.size();
1440 return HWC2_ERROR_HAS_CHANGES;
1441 }
1442
1443 return HWC2_ERROR_NONE;
1444}
1445
1446int32_t PhysicalDevice::setCursorPosition(hwc2_layer_t layerId, int32_t x, int32_t y) {
1447 HwcLayer* layer = getLayerById(layerId);
1448 if (layer && HWC2_COMPOSITION_CURSOR == layer->getCompositionType()) {
1449 framebuffer_info_t* cbInfo = mCursorContext->getInfo();
1450 fb_cursor cinfo;
1451 if (cbInfo->fd < 0) {
1452 ETRACE("setCursorPosition fd=%d", cbInfo->fd );
1453 }else {
1454 cinfo.hot.x = x;
1455 cinfo.hot.y = y;
1456 DTRACE("setCursorPosition x_pos=%d, y_pos=%d", cinfo.hot.x, cinfo.hot.y);
1457
1458 ioctl(cbInfo->fd, FBIOPUT_OSD_CURSOR, &cinfo);
1459 }
1460 } else {
1461 ETRACE("setCursorPosition bad layer.");
1462 return HWC2_ERROR_BAD_LAYER;
1463 }
1464
1465 return HWC2_ERROR_NONE;
1466}
1467
1468
1469/*
1470Operater of framebuffer
1471*/
1472int32_t PhysicalDevice::initDisplay() {
1473 Mutex::Autolock _l(mLock);
1474
1475 if (!mFramebufferHnd) {
1476 // init framebuffer context.
1477 mFramebufferContext = new FBContext();
1478 framebuffer_info_t* fbInfo = mFramebufferContext->getInfo();
1479 // init information from osd.
1480 fbInfo->displayType = mId;
1481 fbInfo->fbIdx = getOsdIdx(mId);
1482 int32_t err = init_frame_buffer_locked(fbInfo);
1483 int32_t bufferSize = fbInfo->finfo.line_length
1484 * fbInfo->info.yres;
1485 DTRACE("init_frame_buffer get fbinfo->fbIdx (%d) "
1486 "fbinfo->info.xres (%d) fbinfo->info.yres (%d)",
1487 fbInfo->fbIdx, fbInfo->info.xres,
1488 fbInfo->info.yres);
1489 int32_t usage = 0;
1490
1491 mFramebufferHnd = new private_handle_t(
1492 private_handle_t::PRIV_FLAGS_FRAMEBUFFER,
1493 usage, fbInfo->fbSize, 0,
1494 0, fbInfo->fd, bufferSize, 0);
1495
1496 DTRACE("init_frame_buffer get frame size %d usage %d",
1497 bufferSize, usage);
1498 }
1499
1500 // init cursor framebuffer
1501 mCursorContext = new FBContext();
1502 framebuffer_info_t* cbInfo = mCursorContext->getInfo();
1503 cbInfo->fd = -1;
1504
1505 //init information from cursor framebuffer.
1506 cbInfo->fbIdx = mId*2+1;
1507 if (1 != cbInfo->fbIdx && 3 != cbInfo->fbIdx) {
1508 ETRACE("invalid fb index: %d, need to check!",
1509 cbInfo->fbIdx);
1510 return 0;
1511 }
1512 int32_t err = init_cursor_buffer_locked(cbInfo);
1513 if (err != 0) {
1514 ETRACE("init_cursor_buffer_locked failed, need to check!");
1515 return 0;
1516 }
1517 ITRACE("init_cursor_buffer get cbinfo->fbIdx (%d) "
1518 "cbinfo->info.xres (%d) cbinfo->info.yres (%d)",
1519 cbInfo->fbIdx,
1520 cbInfo->info.xres,
1521 cbInfo->info.yres);
1522
1523 if ( cbInfo->fd >= 0) {
1524 DTRACE("init_cursor_buffer success!");
1525 }else{
1526 DTRACE("init_cursor_buffer fail!");
1527 }
1528
1529 return 0;
1530}
1531
1532void PhysicalDevice::updateActiveDisplayAttribute() {
1533 hwc2_config_t config;
1534 if (HWC2_ERROR_NONE == mDisplayHdmi->getRealActiveConfig(&config)) {
1535 int32_t period = 0;
1536 mDisplayHdmi->getDisplayAttribute(config, HWC2_ATTRIBUTE_VSYNC_PERIOD, &period);
1537 mVsyncObserver->setRefreshPeriod(period);
1538 }
1539
1540 calReverseScale();
1541}
1542
1543bool PhysicalDevice::updateDisplayConfigs() {
1544 Mutex::Autolock _l(mLock);
1545 framebuffer_info_t* fbinfo = mFramebufferContext->getInfo();
1546 mDisplayHdmi->updateHotplug(mConnectorPresent, *fbinfo);
1547
1548 if (mConnectorPresent) {
1549 updateActiveDisplayAttribute();
1550 } else {
1551 ETRACE("disp: %llu is not connected, should change mode to null", mId);
1552 // mDisplayHdmi->setBestDisplayMode();
1553 return false;
1554 }
1555
1556 // update HDR info.
1557 if (!mHdrCapabilities.init) {
1558 ETRACE("update hdr infomation.");
1559 parseHdrCapabilities();
1560 mHdrCapabilities.init = true;
1561 }
1562
1563 mSecure = mDisplayHdmi->isSecure();
1564 return true;
1565}
1566
1567void PhysicalDevice::onVsync(int64_t timestamp) {
1568 RETURN_VOID_IF_NOT_INIT();
1569 ATRACE("timestamp = %lld", timestamp);
1570
1571 if (!mConnectorPresent)
1572 return;
1573
1574 // notify hwc
1575 mHwc.vsync(mId, timestamp);
1576}
1577
1578void PhysicalDevice::onHotplug(int disp, bool connected) {
1579 RETURN_VOID_IF_NOT_INIT();
1580 ETRACE("connect status = (%d)", connected);
1581
1582 if (!mGetInitState) {
1583 mGetInitState = true;
1584 if (mDisplayHdmi->chkPresent()) {
1585 updateHotplugState(true);
1586 }
1587 }
1588
1589 if (!updateDisplayConfigs())
1590 ETRACE("failed to update display config");
1591
1592 // notify hwc
1593 if (connected)
1594 mHwc.hotplug(disp, connected);
1595}
1596
1597int32_t PhysicalDevice::createVirtualDisplay(
1598 uint32_t width,
1599 uint32_t height,
1600 int32_t* /*android_pixel_format_t*/ format,
1601 hwc2_display_t* outDisplay) {
1602
1603 return HWC2_ERROR_NONE;
1604}
1605
1606int32_t PhysicalDevice::destroyVirtualDisplay(
1607 hwc2_display_t display) {
1608
1609 return HWC2_ERROR_NONE;
1610}
1611
1612int32_t PhysicalDevice::setOutputBuffer(
1613 buffer_handle_t buffer, int32_t releaseFence) {
1614 // Virtual Display Only.
1615 return HWC2_ERROR_NONE;
1616}
1617
1618void PhysicalDevice::updateHotplugState(bool connected) {
1619 Mutex::Autolock _l(mLock);
1620
1621 mConnectorPresent = connected;
1622 // if plug out, need reinit
1623 if (!connected)
1624 memset(&mHdrCapabilities, 0, sizeof(hdr_capabilities_t));
1625}
1626
1627int32_t PhysicalDevice::getLineValue(const char *lineStr, const char *magicStr) {
1628 int len = 0;
1629 char value[100] = {0};
1630 const char *pos = NULL;
1631
1632 if ((NULL == lineStr) || (NULL == magicStr)) {
1633 ETRACE("line string: %s, magic string: %s\n", lineStr, magicStr);
1634 return 0;
1635 }
1636
1637 if (NULL != (pos = strstr(lineStr, magicStr))) {
1638 pos = pos + strlen(magicStr);
1639 const char* start = pos;
1640 while (*start != '\n' && (strlen(start) > 0))
1641 start++;
1642
1643 len = start - pos;
1644 strncpy(value, pos, len);
1645 value[len] = '\0';
1646 return atoi(value);
1647 }
1648
1649 return 0;
1650}
1651
1652/*******************************************
1653* cat /sys/class/amhdmitx/amhdmitx0/hdr_cap
1654* Supported EOTF:
1655* Traditional SDR: 1
1656* Traditional HDR: 0
1657* SMPTE ST 2084: 1
1658* Future EOTF: 0
1659* Supported SMD type1: 1
1660* Luminance Data
1661* Max: 0
1662* Avg: 0
1663* Min: 0
1664* cat /sys/class/amhdmitx/amhdmitx0/dv_cap
1665* DolbyVision1 RX support list:
1666* 2160p30hz: 1
1667* global dimming
1668* colorimetry
1669* IEEEOUI: 0x00d046
1670* DM Ver: 1
1671*******************************************/
1672int32_t PhysicalDevice::parseHdrCapabilities() {
1673 // DolbyVision1
1674 const char *DV_PATH = "/sys/class/amhdmitx/amhdmitx0/dv_cap";
1675 // HDR
1676 const char *HDR_PATH = "/sys/class/amhdmitx/amhdmitx0/hdr_cap";
1677
1678 char buf[1024+1] = {0};
1679 char* pos = buf;
1680 int fd, len;
1681
1682 memset(&mHdrCapabilities, 0, sizeof(hdr_capabilities_t));
1683 if ((fd = open(DV_PATH, O_RDONLY)) < 0) {
1684 ETRACE("open %s fail.", DV_PATH);
1685 goto exit;
1686 }
1687
1688 len = read(fd, buf, 1024);
1689 if (len < 0) {
1690 ETRACE("read error: %s, %s\n", DV_PATH, strerror(errno));
1691 goto exit;
1692 }
1693 close(fd);
1694
1695 if ((NULL != strstr(pos, "2160p30hz")) || (NULL != strstr(pos, "2160p60hz")))
1696 mHdrCapabilities.dvSupport = true;
1697 // dobly version parse end
1698
1699 memset(buf, 0, 1024);
1700 if ((fd = open(HDR_PATH, O_RDONLY)) < 0) {
1701 ETRACE("open %s fail.", HDR_PATH);
1702 goto exit;
1703 }
1704
1705 len = read(fd, buf, 1024);
1706 if (len < 0) {
1707 ETRACE("read error: %s, %s\n", HDR_PATH, strerror(errno));
1708 goto exit;
1709 }
1710
1711 pos = strstr(pos, "SMPTE ST 2084: ");
1712 if ((NULL != pos) && ('1' == *(pos + strlen("SMPTE ST 2084: ")))) {
1713 mHdrCapabilities.hdrSupport = true;
1714
1715 mHdrCapabilities.maxLuminance = getLineValue(pos, "Max: ");
1716 mHdrCapabilities.avgLuminance = getLineValue(pos, "Avg: ");
1717 mHdrCapabilities.minLuminance = getLineValue(pos, "Min: ");
1718 }
1719
1720 ITRACE("dolby version support:%d, hdr support:%d max:%d, avg:%d, min:%d\n",
1721 mHdrCapabilities.dvSupport?1:0, mHdrCapabilities.hdrSupport?1:0, mHdrCapabilities.maxLuminance, mHdrCapabilities.avgLuminance, mHdrCapabilities.minLuminance);
1722exit:
1723 close(fd);
1724 return HWC2_ERROR_NONE;
1725}
1726
1727void PhysicalDevice::dump(Dump& d) {
1728 Mutex::Autolock _l(mLock);
1729 d.append("-------------------------------------------------------------"
1730 "----------------------------------------------------------------\n");
1731 d.append("Device Name: %s (%s), (%f, %f)\n", mName,
1732 mConnectorPresent ? "connected" : "disconnected",
1733 mReverseScaleX, mReverseScaleY);
1734
1735 d.append("isSecure : %s\n", mSecure ? "TRUE" : "FALSE");
1736
1737 mDisplayHdmi->dump(d);
1738
1739#if 0 //all the info already dumped by SurfaceFlinger, comment it.
1740 // dump layer list
1741 d.append(" Layers state:\n");
1742 d.append(" numLayers=%zu\n", mHwcLayers.size());
1743 // d.append(" numChangedTypeLayers=%zu\n", mHwcLayersChangeType.size());
1744 // d.append(" numChangedRequestLayers=%zu\n", mHwcLayersChangeRequest.size());
1745
1746 if (mHwcLayers.size() > 0) {
1747 d.append(
1748 " type | handle | zorder | ds | alpa | tr | blnd |"
1749 " source crop (l,t,r,b) | frame \n"
1750 " -------------+--------------+------------+----+------+----+------+"
1751 "--------------------------------+------------------------\n");
1752 for (uint32_t i=0; i<mHwcLayers.size(); i++) {
1753 hwc2_layer_t layerId = mHwcLayers.keyAt(i);
1754 HwcLayer *layer = mHwcLayers.valueAt(i);
1755 if (layer) layer->dump(d);
1756 }
1757 }
1758#endif
1759
1760 // HDR info
1761 d.append(" HDR Capabilities:\n");
1762 d.append(" DolbyVision1=%zu\n", mHdrCapabilities.dvSupport?1:0);
1763 d.append(" HDR10=%zu, maxLuminance=%zu, avgLuminance=%zu, minLuminance=%zu\n",
1764 mHdrCapabilities.hdrSupport?1:0, mHdrCapabilities.maxLuminance, mHdrCapabilities.avgLuminance, mHdrCapabilities.minLuminance);
1765}
1766
1767} // namespace amlogic
1768} // namespace android
1769