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