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