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