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