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