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