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