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