summaryrefslogtreecommitdiff
path: root/hwc2/common/devices/PhysicalDevice.cpp (plain)
blob: c00a46c5566473273e6390b2b3c0dfb212b1edfb
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
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
1288 if (hnd && (hnd->flags & private_handle_t::PRIV_FLAGS_VIDEO_OMX)) {
1289 videoPresentFlags = 2;
1290 } else if (hnd && (hnd->flags & private_handle_t::PRIV_FLAGS_VIDEO_OVERLAY)) {
1291 videoPresentFlags = 1;
1292 }
1293 }
1294
1295 if (videoPresentFlags == 2) {
1296 mOmxVideoPresent = true;
1297 } else {
1298 mOmxVideoPresent = false;
1299 }
1300 return HWC2_ERROR_NONE;
1301}
1302
1303int32_t PhysicalDevice::beginCompose() {
1304 swapReleaseFence();
1305 // reset layer changed or requested size to zero.
1306 mHwcLayersChangeType.clear();
1307 mHwcLayersChangeRequest.clear();
1308 mHwcGlesLayers.clear();
1309 // deal non secure display device.
1310 mHwcSecureLayers.clear();
1311
1312 memset(&mFbSyncRequest, 0, sizeof(mFbSyncRequest));
1313 mFbSyncRequest.in_fen_fd = -1;
1314
1315 mVideoOverlayLayerId = 0;
1316 mIsContinuousBuf = true;
1317 mIsValidated = false;
1318 mRenderMode = GLES_COMPOSE_MODE;
1319
1320 return HWC2_ERROR_NONE;
1321}
1322
1323int32_t PhysicalDevice::finishCompose() {
1324 HwcLayer* layer = NULL;
1325 // reset layers' acquire fence.
1326 for (uint32_t i=0; i<mHwcLayers.size(); i++) {
1327 hwc2_layer_t layerId = mHwcLayers.keyAt(i);
1328 layer = mHwcLayers.valueAt(i);
1329 if (layer != NULL) {
1330 layer->resetAcquireFence();
1331 }
1332 }
1333
1334 mClientTargetHnd = NULL;
1335 mPreviousRenderMode = mRenderMode;
1336 return HWC2_ERROR_NONE;
1337}
1338
1339int32_t PhysicalDevice::validateDisplay(uint32_t* outNumTypes,
1340 uint32_t* outNumRequests) {
1341 HwcLayer* layer = NULL, *videoLayer = NULL;
1342 hwc_rect_t videoRect;
1343 KeyedVector<hwc2_layer_t, HwcLayer*> composeLayers;
1344 composeLayers.clear();
1345
1346 beginCompose();
1347
1348 if (preValidate() != HWC2_ERROR_NONE) {
1349 return HWC2_ERROR_BAD_LAYER;
1350 }
1351
1352 if (mVideoOverlayLayerId) {
1353 videoLayer = mHwcLayers.valueFor(mVideoOverlayLayerId);
1354 videoRect = videoLayer->getDisplayFrame();
1355 }
1356
1357 for (uint32_t i=0; i<mHwcLayers.size(); i++) {
1358 int overlapType = Utils::OVERLAP_EMPTY;
1359 hwc2_layer_t layerId = mHwcLayers.keyAt(i);
1360 layer = mHwcLayers.valueAt(i);
1361 if (!layer)
1362 continue;
1363
1364 private_handle_t const* hnd = private_handle_t::dynamicCast(layer->getBufferHandle());
1365
1366#ifdef HWC_SUPPORT_SECURE_LAYER
1367 // secure or protected layer.
1368 if (!mSecure && hnd && (hnd->flags & private_handle_t::PRIV_FLAGS_SECURE_PROTECTED)) {
1369 DTRACE("layer's secure or protected buffer flag is set! usage (%x)", hnd->flags);
1370 if (layer->getCompositionType() != HWC2_COMPOSITION_DEVICE) {
1371 mHwcLayersChangeType.add(layerId, layer);
1372 }
1373 mHwcSecureLayers.add(layerId, layer);
1374 continue;
1375 }
1376#endif
1377 if (hnd && hnd->flags & private_handle_t::PRIV_FLAGS_VIDEO_OMX) {
1378 set_omx_pts((char*)hnd->base, &mOmxVideoHandle);
1379 }
1380
1381 if (videoLayer && (layer->getZ() < videoLayer->getZ())) {
1382 DTRACE("Layer covered by video layer.");
1383 hwc_rect_t layerRect = layer->getDisplayFrame();
1384 overlapType = Utils::rectOverlap(layerRect, videoRect);
1385 }
1386
1387 switch (layer->getCompositionType()) {
1388 case HWC2_COMPOSITION_CLIENT:
1389 mHwcGlesLayers.add(layerId, layer);
1390 DTRACE("Meet a client layer!");
1391 break;
1392 case HWC2_COMPOSITION_DEVICE:
1393 if (layerId == mVideoOverlayLayerId) {
1394 mHwcLayersChangeRequest.add(layerId, layer);
1395 } else {
1396 composeLayers.add(layerId, layer);
1397 }
1398 break;
1399 case HWC2_COMPOSITION_SOLID_COLOR:
1400 if (overlapType != Utils::OVERLAP_FULL) {
1401 mHwcGlesLayers.add(layerId, layer);
1402 mHwcLayersChangeType.add(layerId, layer);
1403 }
1404 break;
1405 case HWC2_COMPOSITION_CURSOR:
1406 DTRACE("This is a Cursor layer!");
1407 mHwcLayersChangeRequest.add(layerId, layer);
1408 break;
1409 case HWC2_COMPOSITION_SIDEBAND:
1410 if (layerId == mVideoOverlayLayerId) {
1411 DTRACE("get HWC_SIDEBAND layer, just change to overlay");
1412 mHwcLayersChangeRequest.add(layerId, layer);
1413 mHwcLayersChangeType.add(layerId, layer);
1414 } else {
1415 ETRACE("SIDEBAND not handled.");
1416 }
1417 break;
1418 default:
1419 ETRACE("get layer of unknown composition type (%d)", layer->getCompositionType());
1420 break;
1421 }
1422 }
1423 if (mOmxKeepLastFrame == 1) {
1424 int is_disable_video = -1;
1425 AmVideo::getInstance()->getvideodisable(&is_disable_video);
1426 //ALOGD("is_disable_video %d, mOmxVideoPresent %d",is_disable_video,mOmxVideoPresent);
1427 if (mOmxVideoPresent) {
1428 //enable video layer
1429 if (is_disable_video == 1) {
1430 ALOGI("video layer present, enable video layer");
1431 AmVideo::getInstance()->setvideodisable(2);
1432 }
1433 mVideoLayerOpenByOMX = true;
1434 } else {
1435 //disable video layer.
1436 if (mVideoLayerOpenByOMX) {
1437 if (is_disable_video == 0 || is_disable_video == 2) {
1438 if (mVideoOverlayLayerId == 0) {
1439 ALOGI("no omx video layer, no OVERLAY, set display_mode %d->1",is_disable_video);
1440 AmVideo::getInstance()->setvideodisable(1);
1441 } else {
1442 ALOGI("no omx video layer, but has OVERLAY, not set display_mode");
1443 }
1444 }
1445 mVideoLayerOpenByOMX = false;
1446 }
1447 }
1448 }
1449
1450 bool noDevComp = Utils::checkBoolProp("sys.sf.debug.nohwc");
1451#ifndef USE_CONTINOUS_BUFFER_COMPOSER
1452 DTRACE("No continous buffer composer!");
1453 noDevComp = true;
1454 mIsContinuousBuf = false;
1455#endif
1456
1457 if (mHwcLayers.size() == 0) {
1458 mIsContinuousBuf = false;
1459 }
1460
1461 // dumpLayers(mHwcLayers);
1462 if (mIsContinuousBuf && !noDevComp && (mHwcGlesLayers.size() == 0)) {
1463 mRenderMode = composersFilter(composeLayers);
1464 } else {
1465 mDirectComposeFrameCount = 0;
1466 }
1467
1468 // DEVICE_COMPOSE layers set to CLIENT_COMPOSE layers.
1469 for (int i=0; i<composeLayers.size(); i++) {
1470 mHwcLayersChangeType.add(composeLayers.keyAt(i), composeLayers.valueAt(i));
1471 mHwcGlesLayers.add(composeLayers.keyAt(i), composeLayers.valueAt(i));
1472 }
1473
1474 if (mHwcLayersChangeRequest.size() > 0) {
1475 DTRACE("There are %d layer requests.", mHwcLayersChangeRequest.size());
1476 *outNumRequests = mHwcLayersChangeRequest.size();
1477 }
1478
1479 mIsValidated = true;
1480
1481 if (mHwcLayersChangeType.size() > 0) {
1482 DTRACE("there are %d layer types has changed.", mHwcLayersChangeType.size());
1483 *outNumTypes = mHwcLayersChangeType.size();
1484 return HWC2_ERROR_HAS_CHANGES;
1485 }
1486
1487 return HWC2_ERROR_NONE;
1488}
1489
1490int32_t PhysicalDevice::setCursorPosition(hwc2_layer_t layerId, int32_t x, int32_t y) {
1491 HwcLayer* layer = getLayerById(layerId);
1492 if (layer && HWC2_COMPOSITION_CURSOR == layer->getCompositionType()) {
1493 framebuffer_info_t* cbInfo = mCursorContext->getInfo();
1494 fb_cursor cinfo;
1495 if (cbInfo->fd < 0) {
1496 ETRACE("setCursorPosition fd=%d", cbInfo->fd );
1497 }else {
1498 cinfo.hot.x = x;
1499 cinfo.hot.y = y;
1500 DTRACE("setCursorPosition x_pos=%d, y_pos=%d", cinfo.hot.x, cinfo.hot.y);
1501
1502 ioctl(cbInfo->fd, FBIOPUT_OSD_CURSOR, &cinfo);
1503 }
1504 } else {
1505 ETRACE("setCursorPosition bad layer.");
1506 return HWC2_ERROR_BAD_LAYER;
1507 }
1508
1509 return HWC2_ERROR_NONE;
1510}
1511
1512
1513/*
1514Operater of framebuffer
1515*/
1516int32_t PhysicalDevice::initDisplay() {
1517 Mutex::Autolock _l(mLock);
1518
1519 if (!mFramebufferHnd) {
1520 // init framebuffer context.
1521 mFramebufferContext = new FBContext();
1522 framebuffer_info_t* fbInfo = mFramebufferContext->getInfo();
1523 // init information from osd.
1524 fbInfo->displayType = mId;
1525 fbInfo->fbIdx = getOsdIdx(mId);
1526 int32_t err = init_frame_buffer_locked(fbInfo);
1527 int32_t bufferSize = fbInfo->finfo.line_length
1528 * fbInfo->info.yres;
1529 DTRACE("init_frame_buffer get fbinfo->fbIdx (%d) "
1530 "fbinfo->info.xres (%d) fbinfo->info.yres (%d)",
1531 fbInfo->fbIdx, fbInfo->info.xres,
1532 fbInfo->info.yres);
1533 int32_t usage = 0;
1534
1535 mFramebufferHnd = new private_handle_t(
1536 private_handle_t::PRIV_FLAGS_FRAMEBUFFER,
1537 usage, fbInfo->fbSize, 0,
1538 0, fbInfo->fd, bufferSize, 0);
1539
1540 DTRACE("init_frame_buffer get frame size %d usage %d",
1541 bufferSize, usage);
1542 }
1543
1544 // init cursor framebuffer
1545 mCursorContext = new FBContext();
1546 framebuffer_info_t* cbInfo = mCursorContext->getInfo();
1547 cbInfo->fd = -1;
1548
1549 //init information from cursor framebuffer.
1550 cbInfo->fbIdx = mId*2+1;
1551 if (1 != cbInfo->fbIdx && 3 != cbInfo->fbIdx) {
1552 ETRACE("invalid fb index: %d, need to check!",
1553 cbInfo->fbIdx);
1554 return 0;
1555 }
1556 int32_t err = init_cursor_buffer_locked(cbInfo);
1557 if (err != 0) {
1558 ETRACE("init_cursor_buffer_locked failed, need to check!");
1559 return 0;
1560 }
1561 ITRACE("init_cursor_buffer get cbinfo->fbIdx (%d) "
1562 "cbinfo->info.xres (%d) cbinfo->info.yres (%d)",
1563 cbInfo->fbIdx,
1564 cbInfo->info.xres,
1565 cbInfo->info.yres);
1566
1567 if ( cbInfo->fd >= 0) {
1568 DTRACE("init_cursor_buffer success!");
1569 }else{
1570 DTRACE("init_cursor_buffer fail!");
1571 }
1572
1573 return 0;
1574}
1575
1576void PhysicalDevice::updateActiveDisplayAttribute() {
1577 hwc2_config_t config;
1578 if (HWC2_ERROR_NONE == mDisplayHdmi->getRealActiveConfig(&config)) {
1579 int32_t period = 0;
1580 mDisplayHdmi->getDisplayAttribute(config, HWC2_ATTRIBUTE_VSYNC_PERIOD, &period);
1581 mVsyncObserver->setRefreshPeriod(period);
1582 }
1583
1584 calReverseScale();
1585}
1586
1587bool PhysicalDevice::updateDisplayConfigs() {
1588 Mutex::Autolock _l(mLock);
1589 framebuffer_info_t* fbinfo = mFramebufferContext->getInfo();
1590 mDisplayHdmi->updateHotplug(mConnectorPresent, *fbinfo);
1591
1592 if (mConnectorPresent) {
1593 updateActiveDisplayAttribute();
1594 } else {
1595 ETRACE("disp: %llu is not connected, should change mode to null", mId);
1596 // mDisplayHdmi->setBestDisplayMode();
1597 return false;
1598 }
1599
1600 // update HDR info.
1601 if (!mHdrCapabilities.init) {
1602 ETRACE("update hdr infomation.");
1603 parseHdrCapabilities();
1604 mHdrCapabilities.init = true;
1605 }
1606
1607 mSecure = mDisplayHdmi->isSecure();
1608 return true;
1609}
1610
1611void PhysicalDevice::onVsync(int64_t timestamp) {
1612 RETURN_VOID_IF_NOT_INIT();
1613 ATRACE("timestamp = %lld", timestamp);
1614
1615 if (!mConnectorPresent)
1616 return;
1617
1618 // notify hwc
1619 mHwc.vsync(mId, timestamp);
1620}
1621
1622void PhysicalDevice::onHotplug(int disp, bool connected) {
1623 RETURN_VOID_IF_NOT_INIT();
1624 ETRACE("connect status = (%d)", connected);
1625
1626 if (!mGetInitState) {
1627 mGetInitState = true;
1628 if (mDisplayHdmi->chkPresent()) {
1629 updateHotplugState(true);
1630 }
1631 }
1632
1633 if (!updateDisplayConfigs())
1634 ETRACE("failed to update display config");
1635
1636 // notify hwc
1637 if (connected)
1638 mHwc.hotplug(disp, connected);
1639}
1640
1641int32_t PhysicalDevice::createVirtualDisplay(
1642 uint32_t width,
1643 uint32_t height,
1644 int32_t* /*android_pixel_format_t*/ format,
1645 hwc2_display_t* outDisplay) {
1646
1647 return HWC2_ERROR_NONE;
1648}
1649
1650int32_t PhysicalDevice::destroyVirtualDisplay(
1651 hwc2_display_t display) {
1652
1653 return HWC2_ERROR_NONE;
1654}
1655
1656int32_t PhysicalDevice::setOutputBuffer(
1657 buffer_handle_t buffer, int32_t releaseFence) {
1658 // Virtual Display Only.
1659 return HWC2_ERROR_NONE;
1660}
1661
1662void PhysicalDevice::updateHotplugState(bool connected) {
1663 Mutex::Autolock _l(mLock);
1664
1665 mConnectorPresent = connected;
1666 // if plug out, need reinit
1667 if (!connected)
1668 memset(&mHdrCapabilities, 0, sizeof(hdr_capabilities_t));
1669}
1670
1671int32_t PhysicalDevice::getLineValue(const char *lineStr, const char *magicStr) {
1672 int len = 0;
1673 char value[100] = {0};
1674 const char *pos = NULL;
1675
1676 if ((NULL == lineStr) || (NULL == magicStr)) {
1677 ETRACE("line string: %s, magic string: %s\n", lineStr, magicStr);
1678 return 0;
1679 }
1680
1681 if (NULL != (pos = strstr(lineStr, magicStr))) {
1682 pos = pos + strlen(magicStr);
1683 const char* start = pos;
1684 while (*start != '\n' && (strlen(start) > 0))
1685 start++;
1686
1687 len = start - pos;
1688 strncpy(value, pos, len);
1689 value[len] = '\0';
1690 return atoi(value);
1691 }
1692
1693 return 0;
1694}
1695
1696/*******************************************
1697* cat /sys/class/amhdmitx/amhdmitx0/hdr_cap
1698* Supported EOTF:
1699* Traditional SDR: 1
1700* Traditional HDR: 0
1701* SMPTE ST 2084: 1
1702* Future EOTF: 0
1703* Supported SMD type1: 1
1704* Luminance Data
1705* Max: 0
1706* Avg: 0
1707* Min: 0
1708* cat /sys/class/amhdmitx/amhdmitx0/dv_cap
1709* DolbyVision1 RX support list:
1710* 2160p30hz: 1
1711* global dimming
1712* colorimetry
1713* IEEEOUI: 0x00d046
1714* DM Ver: 1
1715*******************************************/
1716int32_t PhysicalDevice::parseHdrCapabilities() {
1717 // DolbyVision1
1718 const char *DV_PATH = "/sys/class/amhdmitx/amhdmitx0/dv_cap";
1719 // HDR
1720 const char *HDR_PATH = "/sys/class/amhdmitx/amhdmitx0/hdr_cap";
1721
1722 char buf[1024+1] = {0};
1723 char* pos = buf;
1724 int fd, len;
1725
1726 memset(&mHdrCapabilities, 0, sizeof(hdr_capabilities_t));
1727 if ((fd = open(DV_PATH, O_RDONLY)) < 0) {
1728 ETRACE("open %s fail.", DV_PATH);
1729 goto exit;
1730 }
1731
1732 len = read(fd, buf, 1024);
1733 if (len < 0) {
1734 ETRACE("read error: %s, %s\n", DV_PATH, strerror(errno));
1735 goto exit;
1736 }
1737 close(fd);
1738
1739 if ((NULL != strstr(pos, "2160p30hz")) || (NULL != strstr(pos, "2160p60hz")))
1740 mHdrCapabilities.dvSupport = true;
1741 // dobly version parse end
1742
1743 memset(buf, 0, 1024);
1744 if ((fd = open(HDR_PATH, O_RDONLY)) < 0) {
1745 ETRACE("open %s fail.", HDR_PATH);
1746 goto exit;
1747 }
1748
1749 len = read(fd, buf, 1024);
1750 if (len < 0) {
1751 ETRACE("read error: %s, %s\n", HDR_PATH, strerror(errno));
1752 goto exit;
1753 }
1754
1755 pos = strstr(pos, "SMPTE ST 2084: ");
1756 if ((NULL != pos) && ('1' == *(pos + strlen("SMPTE ST 2084: ")))) {
1757 mHdrCapabilities.hdrSupport = true;
1758
1759 mHdrCapabilities.maxLuminance = getLineValue(pos, "Max: ");
1760 mHdrCapabilities.avgLuminance = getLineValue(pos, "Avg: ");
1761 mHdrCapabilities.minLuminance = getLineValue(pos, "Min: ");
1762 }
1763
1764 ITRACE("dolby version support:%d, hdr support:%d max:%d, avg:%d, min:%d\n",
1765 mHdrCapabilities.dvSupport?1:0, mHdrCapabilities.hdrSupport?1:0, mHdrCapabilities.maxLuminance, mHdrCapabilities.avgLuminance, mHdrCapabilities.minLuminance);
1766exit:
1767 close(fd);
1768 return HWC2_ERROR_NONE;
1769}
1770
1771void PhysicalDevice::dump(Dump& d) {
1772 Mutex::Autolock _l(mLock);
1773 d.append("-------------------------------------------------------------"
1774 "----------------------------------------------------------------\n");
1775 d.append("Device Name: %s (%s), (%f, %f)\n", mName,
1776 mConnectorPresent ? "connected" : "disconnected",
1777 mReverseScaleX, mReverseScaleY);
1778
1779 d.append("isSecure : %s\n", mSecure ? "TRUE" : "FALSE");
1780
1781 mDisplayHdmi->dump(d);
1782
1783#if 0 //all the info already dumped by SurfaceFlinger, comment it.
1784 // dump layer list
1785 d.append(" Layers state:\n");
1786 d.append(" numLayers=%zu\n", mHwcLayers.size());
1787 // d.append(" numChangedTypeLayers=%zu\n", mHwcLayersChangeType.size());
1788 // d.append(" numChangedRequestLayers=%zu\n", mHwcLayersChangeRequest.size());
1789
1790 if (mHwcLayers.size() > 0) {
1791 d.append(
1792 " type | handle | zorder | ds | alpa | tr | blnd |"
1793 " source crop (l,t,r,b) | frame \n"
1794 " -------------+--------------+------------+----+------+----+------+"
1795 "--------------------------------+------------------------\n");
1796 for (uint32_t i=0; i<mHwcLayers.size(); i++) {
1797 hwc2_layer_t layerId = mHwcLayers.keyAt(i);
1798 HwcLayer *layer = mHwcLayers.valueAt(i);
1799 if (layer) layer->dump(d);
1800 }
1801 }
1802#endif
1803
1804 // HDR info
1805 d.append(" HDR Capabilities:\n");
1806 d.append(" DolbyVision1=%zu\n", mHdrCapabilities.dvSupport?1:0);
1807 d.append(" HDR10=%zu, maxLuminance=%zu, avgLuminance=%zu, minLuminance=%zu\n",
1808 mHdrCapabilities.hdrSupport?1:0, mHdrCapabilities.maxLuminance, mHdrCapabilities.avgLuminance, mHdrCapabilities.minLuminance);
1809}
1810
1811} // namespace amlogic
1812} // namespace android
1813