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