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