summaryrefslogtreecommitdiff
path: root/hwc2/MesonHwc2.cpp (plain)
blob: dcc73ac1da654e5f8c3d6b7b40985bf4c0c77663
1/*
2 * Copyright (c) 2017 Amlogic, Inc. All rights reserved.
3 *
4 * This source code is subject to the terms and conditions defined in the
5 * file 'LICENSE' which is part of this source code package.
6 *
7 * Description:
8 */
9
10#include <unistd.h>
11#include <thread>
12#include <mutex>
13#include <condition_variable>
14
15#include <BasicTypes.h>
16#include <MesonLog.h>
17#include <DebugHelper.h>
18#include <HwcConfig.h>
19#include <HwcVsync.h>
20#include <HwcDisplayPipe.h>
21#include <misc.h>
22#include <systemcontrol.h>
23
24#include "MesonHwc2Defs.h"
25#include "MesonHwc2.h"
26#include "VirtualDisplay.h"
27
28#define GET_REQUEST_FROM_PROP 1
29
30#define CHECK_DISPLAY_VALID(display) \
31 if (isDisplayValid(display) == false) { \
32 MESON_LOGE("(%s) met invalid display id (%d)", \
33 __func__, (int)display); \
34 return HWC2_ERROR_BAD_DISPLAY; \
35 }
36
37#define GET_HWC_DISPLAY(display) \
38 std::shared_ptr<Hwc2Display> hwcDisplay; \
39 std::map<hwc2_display_t, std::shared_ptr<Hwc2Display>>::iterator it = \
40 mDisplays.find(display); \
41 if (it != mDisplays.end()) { \
42 hwcDisplay = it->second; \
43 } else {\
44 MESON_LOGE("(%s) met invalid display id (%d)",\
45 __func__, (int)display); \
46 return HWC2_ERROR_BAD_DISPLAY; \
47 }
48
49#define GET_HWC_LAYER(display, id) \
50 std::shared_ptr<Hwc2Layer> hwcLayer = display->getLayerById(id); \
51 if (hwcLayer.get() == NULL) { \
52 MESON_LOGE("(%s) met invalid layer id (%d) in display (%p)",\
53 __func__, (int)id, display.get()); \
54 return HWC2_ERROR_BAD_LAYER; \
55 }
56
57
58#ifdef GET_REQUEST_FROM_PROP
59static bool m3DMode = false;
60static bool mKeyStoneMode = false;
61#endif
62
63ANDROID_SINGLETON_STATIC_INSTANCE(MesonHwc2)
64
65/************************************************************
66* Hal Interface
67************************************************************/
68void MesonHwc2::dump(uint32_t* outSize, char* outBuffer) {
69 if (outBuffer == NULL) {
70 *outSize = 8192;
71 return ;
72 }
73
74 String8 dumpstr;
75 DebugHelper::getInstance().resolveCmd();
76
77#ifdef HWC_RELEASE
78 dumpstr.append("\nMesonHwc2 state(RELEASE):\n");
79#else
80 dumpstr.append("\nMesonHwc2 state(DEBUG):\n");
81#endif
82
83 if (DebugHelper::getInstance().dumpDetailInfo()) {
84 HwcConfig::dump(dumpstr);
85 }
86
87 // dump composer status
88 std::map<hwc2_display_t, std::shared_ptr<Hwc2Display>>::iterator it;
89 for (it = mDisplays.begin(); it != mDisplays.end(); it++) {
90 it->second->dump(dumpstr);
91 }
92
93 DebugHelper::getInstance().dump(dumpstr);
94 dumpstr.append("\n");
95
96 strncpy(outBuffer, dumpstr.string(), dumpstr.size() > 8192 ? 8191 : dumpstr.size());
97}
98
99void MesonHwc2::getCapabilities(uint32_t* outCount,
100 int32_t* outCapabilities) {
101 *outCount = 1;
102 if (outCapabilities) {
103 *outCount = 1;
104 outCapabilities[0] = HWC2_CAPABILITY_SIDEBAND_STREAM;
105 }
106}
107
108int32_t MesonHwc2::getClientTargetSupport(hwc2_display_t display,
109 uint32_t width __unused, uint32_t height __unused, int32_t format, int32_t dataspace) {
110 GET_HWC_DISPLAY(display);
111 if (format == HAL_PIXEL_FORMAT_RGBA_8888 &&
112 dataspace == HAL_DATASPACE_UNKNOWN) {
113 return HWC2_ERROR_NONE;
114 }
115
116 MESON_LOGE("getClientTargetSupport failed: format (%d), dataspace (%d)",
117 format, dataspace);
118 return HWC2_ERROR_UNSUPPORTED;
119}
120
121int32_t MesonHwc2::registerCallback(int32_t descriptor,
122 hwc2_callback_data_t callbackData, hwc2_function_pointer_t pointer) {
123 hwc2_error_t ret = HWC2_ERROR_NONE;
124
125 switch (descriptor) {
126 case HWC2_CALLBACK_HOTPLUG:
127 /* For android:
128 When primary display is hdmi, we should always return connected event
129 to surfaceflinger, or surfaceflinger will not boot and wait
130 connected event.
131 */
132 mHotplugFn = reinterpret_cast<HWC2_PFN_HOTPLUG>(pointer);
133 mHotplugData = callbackData;
134
135 /*always to call hotplug for primary display,
136 * for android always think primary is always connected.
137 */
138 if (mHotplugFn) {
139 mHotplugFn(mHotplugData, HWC_DISPLAY_PRIMARY, true);
140 if (HwcConfig::getDisplayNum() > 1) {
141 mHotplugFn(mHotplugData, HWC_DISPLAY_EXTERNAL, true);
142 }
143 }
144 break;
145 case HWC2_CALLBACK_REFRESH:
146 mRefreshFn = reinterpret_cast<HWC2_PFN_REFRESH>(pointer);
147 mRefreshData = callbackData;
148 break;
149 case HWC2_CALLBACK_VSYNC:
150 mVsyncFn = reinterpret_cast<HWC2_PFN_VSYNC>(pointer);
151 mVsyncData = callbackData;
152 break;
153
154 default:
155 MESON_LOGE("register unknown callback (%d)", descriptor);
156 ret = HWC2_ERROR_UNSUPPORTED;
157 break;
158 }
159
160 return ret;
161}
162
163int32_t MesonHwc2::getDisplayName(hwc2_display_t display,
164 uint32_t* outSize, char* outName) {
165 GET_HWC_DISPLAY(display);
166 const char * name = hwcDisplay->getName();
167 if (name == NULL) {
168 MESON_LOGE("getDisplayName (%d) failed", (int)display);
169 } else {
170 *outSize = strlen(name) + 1;
171 if (outName) {
172 strcpy(outName, name);
173 }
174 }
175 return HWC2_ERROR_NONE;
176}
177
178int32_t MesonHwc2::getDisplayType(hwc2_display_t display,
179 int32_t* outType) {
180 GET_HWC_DISPLAY(display);
181
182 if (display < HWC_NUM_PHYSICAL_DISPLAY_TYPES) {
183 *outType = HWC2_DISPLAY_TYPE_PHYSICAL;
184 } else {
185 *outType = HWC2_DISPLAY_TYPE_VIRTUAL;
186 }
187
188 return HWC2_ERROR_NONE;
189}
190
191int32_t MesonHwc2::getDozeSupport(hwc2_display_t display,
192 int32_t* outSupport) {
193 /*No doze support now.*/
194 CHECK_DISPLAY_VALID(display);
195 *outSupport = 0;
196 return HWC2_ERROR_NONE;
197}
198
199int32_t MesonHwc2::getColorModes(hwc2_display_t display,
200 uint32_t* outNumModes, int32_t* outModes) {
201 CHECK_DISPLAY_VALID(display);
202 /*Only support native color mode.*/
203 *outNumModes = 1;
204 if (outModes) {
205 outModes[0] = HAL_COLOR_MODE_NATIVE;
206 }
207 return HWC2_ERROR_NONE;
208}
209
210int32_t MesonHwc2::setColorMode(hwc2_display_t display, int32_t mode __unused) {
211 CHECK_DISPLAY_VALID(display);
212 if (mode < HAL_COLOR_MODE_NATIVE)
213 return HWC2_ERROR_BAD_PARAMETER;
214
215 if (mode == HAL_COLOR_MODE_NATIVE)
216 return HWC2_ERROR_NONE;
217 else
218 return HWC2_ERROR_UNSUPPORTED;
219}
220
221int32_t MesonHwc2::setColorTransform(hwc2_display_t display,
222 const float* matrix, int32_t hint) {
223 GET_HWC_DISPLAY(display);
224 return hwcDisplay->setColorTransform(matrix, (android_color_transform_t)hint);
225}
226
227int32_t MesonHwc2::getHdrCapabilities(hwc2_display_t display,
228 uint32_t* outNumTypes, int32_t* outTypes, float* outMaxLuminance,
229 float* outMaxAverageLuminance, float* outMinLuminance) {
230 GET_HWC_DISPLAY(display);
231 const drm_hdr_capabilities_t * caps = hwcDisplay->getHdrCapabilities();
232 if (caps) {
233 bool getInfo = false;
234 if (outTypes)
235 getInfo = true;
236
237 if (caps->DolbyVisionSupported) {
238 *outNumTypes = *outNumTypes + 1;
239 if (getInfo) {
240 *outTypes++ = HAL_HDR_DOLBY_VISION;
241 }
242 }
243 if (caps->HLGSupported) {
244 *outNumTypes = *outNumTypes + 1;
245 if (getInfo) {
246 *outTypes++ = HAL_HDR_HLG;
247 }
248 }
249 if (caps->HDR10Supported) {
250 *outNumTypes = *outNumTypes + 1;
251 if (getInfo) {
252 *outTypes++ = HAL_HDR_HDR10;
253 }
254 }
255
256 if (caps->HDR10PlusSupported) {
257 *outNumTypes = *outNumTypes + 1;
258 if (getInfo) {
259 *outTypes++ = HAL_HDR_HDR10_PLUS;
260 }
261 }
262
263 if (getInfo) {
264 *outMaxLuminance = caps->maxLuminance;
265 *outMaxAverageLuminance = caps->avgLuminance;
266 *outMinLuminance = caps->minLuminance;
267 }
268 } else {
269 *outNumTypes = 0;
270 }
271
272 return HWC2_ERROR_NONE;
273}
274
275int32_t MesonHwc2::setPowerMode(hwc2_display_t display,
276 int32_t mode) {
277 GET_HWC_DISPLAY(display);
278 return hwcDisplay->setPowerMode((hwc2_power_mode_t)mode);
279}
280
281int32_t MesonHwc2::setVsyncEnable(hwc2_display_t display,
282 int32_t enabled) {
283 GET_HWC_DISPLAY(display);
284 return hwcDisplay->setVsyncEnable((hwc2_vsync_t)enabled);
285}
286
287int32_t MesonHwc2::getActiveConfig(hwc2_display_t display,
288 hwc2_config_t* outConfig) {
289 GET_HWC_DISPLAY(display);
290 return hwcDisplay->getActiveConfig(outConfig);
291}
292
293int32_t MesonHwc2::getDisplayConfigs(hwc2_display_t display,
294 uint32_t* outNumConfigs, hwc2_config_t* outConfigs) {
295 GET_HWC_DISPLAY(display);
296 return hwcDisplay->getDisplayConfigs(outNumConfigs, outConfigs);
297}
298
299int32_t MesonHwc2::setActiveConfig(hwc2_display_t display,
300 hwc2_config_t config) {
301 GET_HWC_DISPLAY(display);
302 return hwcDisplay->setActiveConfig(config);
303}
304
305int32_t MesonHwc2::getDisplayAttribute(hwc2_display_t display,
306 hwc2_config_t config, int32_t attribute, int32_t* outValue) {
307 GET_HWC_DISPLAY(display);
308 return hwcDisplay->getDisplayAttribute(config, attribute, outValue);
309}
310
311/*************Virtual display api below*************/
312int32_t MesonHwc2::createVirtualDisplay(uint32_t width, uint32_t height,
313 int32_t* format, hwc2_display_t* outDisplay) {
314 MESON_LOG_EMPTY_FUN();
315 UNUSED(width);
316 UNUSED(height);
317 UNUSED(format);
318 UNUSED(outDisplay);
319 return HWC2_ERROR_NONE;
320}
321
322int32_t MesonHwc2::destroyVirtualDisplay(hwc2_display_t display) {
323 MESON_LOG_EMPTY_FUN();
324 UNUSED(display);
325 return HWC2_ERROR_NONE;
326}
327
328int32_t MesonHwc2::setOutputBuffer(hwc2_display_t display,
329 buffer_handle_t buffer, int32_t releaseFence) {
330 MESON_LOG_EMPTY_FUN();
331 UNUSED(display);
332 UNUSED(buffer);
333 UNUSED(releaseFence);
334 return HWC2_ERROR_NONE;
335}
336
337uint32_t MesonHwc2::getMaxVirtualDisplayCount() {
338 return MESON_VIRTUAL_DISPLAY_MAX_COUNT;
339}
340
341/*************Compose api below*************/
342int32_t MesonHwc2::acceptDisplayChanges(hwc2_display_t display) {
343 GET_HWC_DISPLAY(display);
344 return hwcDisplay->acceptDisplayChanges();
345}
346
347int32_t MesonHwc2::getChangedCompositionTypes( hwc2_display_t display,
348 uint32_t* outNumElements, hwc2_layer_t* outLayers, int32_t* outTypes) {
349 GET_HWC_DISPLAY(display);
350 return hwcDisplay->getChangedCompositionTypes(outNumElements,
351 outLayers, outTypes);
352}
353
354int32_t MesonHwc2::getDisplayRequests(hwc2_display_t display,
355 int32_t* outDisplayRequests, uint32_t* outNumElements,
356 hwc2_layer_t* outLayers, int32_t* outLayerRequests) {
357 GET_HWC_DISPLAY(display);
358 return hwcDisplay->getDisplayRequests(outDisplayRequests, outNumElements,
359 outLayers, outLayerRequests);
360}
361
362int32_t MesonHwc2::setClientTarget(hwc2_display_t display,
363 buffer_handle_t target, int32_t acquireFence,
364 int32_t dataspace, hwc_region_t damage) {
365 GET_HWC_DISPLAY(display);
366 return hwcDisplay->setClientTarget(target, acquireFence,
367 dataspace, damage);
368}
369
370int32_t MesonHwc2::getReleaseFences(hwc2_display_t display,
371 uint32_t* outNumElements, hwc2_layer_t* outLayers, int32_t* outFences) {
372 GET_HWC_DISPLAY(display);
373 return hwcDisplay->getReleaseFences(outNumElements,
374 outLayers, outFences);
375}
376
377int32_t MesonHwc2::validateDisplay(hwc2_display_t display,
378 uint32_t* outNumTypes, uint32_t* outNumRequests) {
379 GET_HWC_DISPLAY(display);
380 /*handle display request*/
381 uint32_t request = getDisplayRequest();
382 setCalibrateInfo(display);
383 if (request != 0) {
384 handleDisplayRequest(request);
385 }
386
387 return hwcDisplay->validateDisplay(outNumTypes,
388 outNumRequests);
389}
390
391int32_t MesonHwc2::presentDisplay(hwc2_display_t display,
392 int32_t* outPresentFence) {
393 GET_HWC_DISPLAY(display);
394 return hwcDisplay->presentDisplay(outPresentFence);
395}
396
397/*************Layer api below*************/
398int32_t MesonHwc2::createLayer(hwc2_display_t display, hwc2_layer_t* outLayer) {
399 GET_HWC_DISPLAY(display);
400 return hwcDisplay->createLayer(outLayer);
401}
402
403int32_t MesonHwc2::destroyLayer(hwc2_display_t display, hwc2_layer_t layer) {
404 GET_HWC_DISPLAY(display);
405 return hwcDisplay->destroyLayer(layer);
406}
407
408int32_t MesonHwc2::setCursorPosition(hwc2_display_t display,
409 hwc2_layer_t layer, int32_t x, int32_t y) {
410 GET_HWC_DISPLAY(display);
411 return hwcDisplay->setCursorPosition(layer, x, y);
412}
413
414int32_t MesonHwc2::setLayerBuffer(hwc2_display_t display, hwc2_layer_t layer,
415 buffer_handle_t buffer, int32_t acquireFence) {
416 GET_HWC_DISPLAY(display);
417 GET_HWC_LAYER(hwcDisplay, layer);
418 return hwcLayer->setBuffer(buffer, acquireFence);
419}
420
421int32_t MesonHwc2::setLayerSurfaceDamage(hwc2_display_t display,
422 hwc2_layer_t layer, hwc_region_t damage) {
423 GET_HWC_DISPLAY(display);
424 GET_HWC_LAYER(hwcDisplay, layer);
425 return hwcLayer->setSurfaceDamage(damage);
426}
427
428int32_t MesonHwc2::setLayerBlendMode(hwc2_display_t display,
429 hwc2_layer_t layer, int32_t mode) {
430 GET_HWC_DISPLAY(display);
431 GET_HWC_LAYER(hwcDisplay, layer);
432 return hwcLayer->setBlendMode((hwc2_blend_mode_t)mode);
433}
434
435int32_t MesonHwc2::setLayerColor(hwc2_display_t display,
436 hwc2_layer_t layer, hwc_color_t color) {
437 GET_HWC_DISPLAY(display);
438 GET_HWC_LAYER(hwcDisplay, layer);
439 return hwcLayer->setColor(color);
440}
441
442int32_t MesonHwc2::setLayerCompositionType(hwc2_display_t display,
443 hwc2_layer_t layer, int32_t type) {
444 GET_HWC_DISPLAY(display);
445 GET_HWC_LAYER(hwcDisplay, layer);
446 return hwcLayer->setCompositionType((hwc2_composition_t)type);
447}
448
449int32_t MesonHwc2::setLayerDataspace(hwc2_display_t display,
450 hwc2_layer_t layer, int32_t dataspace) {
451 GET_HWC_DISPLAY(display);
452 GET_HWC_LAYER(hwcDisplay, layer);
453 return hwcLayer->setDataspace((android_dataspace_t)dataspace);
454}
455
456int32_t MesonHwc2::setLayerDisplayFrame(hwc2_display_t display,
457 hwc2_layer_t layer, hwc_rect_t frame) {
458 GET_HWC_DISPLAY(display);
459 GET_HWC_LAYER(hwcDisplay, layer);
460 return hwcLayer->setDisplayFrame(frame);
461}
462
463int32_t MesonHwc2::setLayerPlaneAlpha(hwc2_display_t display,
464 hwc2_layer_t layer, float alpha) {
465 GET_HWC_DISPLAY(display);
466 GET_HWC_LAYER(hwcDisplay, layer);
467 return hwcLayer->setPlaneAlpha(alpha);
468}
469
470int32_t MesonHwc2::setLayerSidebandStream(hwc2_display_t display,
471 hwc2_layer_t layer, const native_handle_t* stream) {
472 GET_HWC_DISPLAY(display);
473 GET_HWC_LAYER(hwcDisplay, layer);
474 return hwcLayer->setSidebandStream(stream);
475}
476
477int32_t MesonHwc2::setLayerSourceCrop(hwc2_display_t display,
478 hwc2_layer_t layer, hwc_frect_t crop) {
479 GET_HWC_DISPLAY(display);
480 GET_HWC_LAYER(hwcDisplay, layer);
481 return hwcLayer->setSourceCrop(crop);
482}
483
484int32_t MesonHwc2::setLayerTransform(hwc2_display_t display,
485 hwc2_layer_t layer, int32_t transform) {
486 GET_HWC_DISPLAY(display);
487 GET_HWC_LAYER(hwcDisplay, layer);
488 return hwcLayer->setTransform((hwc_transform_t)transform);
489}
490
491int32_t MesonHwc2::setLayerVisibleRegion(hwc2_display_t display,
492 hwc2_layer_t layer, hwc_region_t visible) {
493 GET_HWC_DISPLAY(display);
494 GET_HWC_LAYER(hwcDisplay, layer);
495 return hwcLayer->setVisibleRegion(visible);
496}
497
498int32_t MesonHwc2::setLayerZorder(hwc2_display_t display,
499 hwc2_layer_t layer, uint32_t z) {
500 GET_HWC_DISPLAY(display);
501 GET_HWC_LAYER(hwcDisplay, layer);
502 return hwcLayer->setZorder(z);
503}
504
505int32_t MesonHwc2::getRenderIntents(hwc2_display_t display,
506 int32_t mode, uint32_t* outNumIntents, int32_t* outIntents) {
507 GET_HWC_DISPLAY(display);
508
509 if (mode < HAL_COLOR_MODE_NATIVE)
510 return HWC2_ERROR_BAD_PARAMETER;
511 if (mode != HAL_COLOR_MODE_NATIVE)
512 return HWC2_ERROR_UNSUPPORTED;
513
514 *outNumIntents = 1;
515 if (outIntents) {
516 *outIntents = HAL_RENDER_INTENT_COLORIMETRIC;
517 }
518
519 return HWC2_ERROR_NONE;
520}
521
522int32_t MesonHwc2::setColorModeWithRenderIntent(
523 hwc2_display_t display, int32_t mode, int32_t intent) {
524 GET_HWC_DISPLAY(display);
525
526 if (mode < HAL_COLOR_MODE_NATIVE ||
527 intent < HAL_RENDER_INTENT_COLORIMETRIC)
528 return HWC2_ERROR_BAD_PARAMETER;
529 if (mode != HAL_COLOR_MODE_NATIVE ||
530 intent != HAL_RENDER_INTENT_COLORIMETRIC)
531 return HWC2_ERROR_UNSUPPORTED;
532
533 return HWC2_ERROR_NONE;
534}
535
536#ifdef HWC_HDR_METADATA_SUPPORT
537int32_t MesonHwc2::setLayerPerFrameMetadata(
538 hwc2_display_t display, hwc2_layer_t layer,
539 uint32_t numElements, const int32_t* /*hw2_per_frame_metadata_key_t*/ keys,
540 const float* metadata) {
541 GET_HWC_DISPLAY(display);
542 GET_HWC_LAYER(hwcDisplay, layer);
543 return hwcLayer->setPerFrameMetadata(numElements, keys, metadata);
544}
545
546int32_t MesonHwc2::getPerFrameMetadataKeys(
547 hwc2_display_t display,
548 uint32_t* outNumKeys,
549 int32_t* /*hwc2_per_frame_metadata_key_t*/ outKeys) {
550 GET_HWC_DISPLAY(display);
551 return hwcDisplay->getFrameMetadataKeys(outNumKeys, outKeys);
552}
553#endif
554
555int32_t MesonHwc2::getDisplayIdentificationData(hwc2_display_t display, uint8_t* outPort,
556 uint32_t* outDataSize, uint8_t* outData) {
557 std::vector<uint8_t> edid;
558 uint32_t port;
559 GET_HWC_DISPLAY(display);
560 if (0 != hwcDisplay->getDisplayIdentificationData(port, edid)) {
561 return HWC2_ERROR_UNSUPPORTED;
562 }
563 if (outData == nullptr) {
564 *outDataSize = edid.size();
565 } else {
566 if (*outDataSize != edid.size()) {
567 return HWC2_ERROR_BAD_PARAMETER;
568 }
569 memcpy(outData, edid.data(), sizeof(uint8_t) * edid.size());
570 }
571 *outPort = (uint8_t)port;
572 return HWC2_ERROR_NONE;
573}
574
575int32_t MesonHwc2::getDisplayCapabilities(hwc2_display_t display, uint32_t* outNumCapabilities, uint32_t* outCapabilities) {
576 GET_HWC_DISPLAY(display);
577 return hwcDisplay->getDisplayCapabilities(outNumCapabilities, outCapabilities);
578}
579
580int32_t MesonHwc2::getDisplayBrightnessSupport(hwc2_display_t display, bool* outSupport) {
581 GET_HWC_DISPLAY(display);
582 *outSupport = false;
583 return HWC2_ERROR_NONE;
584}
585
586int32_t MesonHwc2::setDisplayBrightness(hwc2_display_t display, float brightness) {
587 GET_HWC_DISPLAY(display);
588 (void) brightness;
589 return HWC2_ERROR_UNSUPPORTED;
590}
591
592/**********************Amlogic ext display interface*******************/
593int32_t MesonHwc2::setPostProcessor(bool bEnable) {
594 mDisplayRequests |= bEnable ? rPostProcessorStart : rPostProcessorStop;
595 return 0;
596}
597
598int32_t MesonHwc2::setCalibrateInfo(hwc2_display_t display){
599 GET_HWC_DISPLAY(display);
600 int32_t caliX,caliY,caliW,caliH;
601 static int cali[4];
602 drm_mode_info_t mDispMode;
603 hwcDisplay->getDispMode(mDispMode);
604
605 if (HwcConfig::getPipeline() == HWC_PIPE_LOOPBACK) {
606 caliX = caliY = 0;
607 caliW = mDispMode.pixelW;
608 caliH = mDispMode.pixelH;
609#ifdef GET_REQUEST_FROM_PROP
610 if (mKeyStoneMode) {
611 caliX = 1;
612 caliY = 1;
613 caliW = mDispMode.pixelW - 2;
614 caliH = mDispMode.pixelH - 2;
615 }
616#endif
617 } else {
618 /*default info*/
619 caliX = 0;
620 caliY = 0;
621 caliW = mDispMode.pixelW;
622 caliH = mDispMode.pixelH;
623 if (!HwcConfig::preDisplayCalibrateEnabled()) {
624 /*get post calibrate info.*/
625 /*for interlaced, we do thing, osd driver will take care of it.*/
626 int calibrateCoordinates[4];
627 std::string dispModeStr(mDispMode.name);
628 if (0 == sc_get_osd_position(dispModeStr, calibrateCoordinates)) {
629 memcpy(cali, calibrateCoordinates, sizeof(int) * 4);
630 } else {
631 MESON_LOGD("(%s): sc_get_osd_position failed, use backup coordinates.", __func__);
632 }
633 caliX = cali[0];
634 caliY = cali[1];
635 caliW = cali[2];
636 caliH = cali[3];
637 }
638 }
639 return hwcDisplay->setCalibrateInfo(caliX,caliY,caliW,caliH);
640}
641
642uint32_t MesonHwc2::getDisplayRequest() {
643 /*read extend prop to update display request.*/
644#ifdef GET_REQUEST_FROM_PROP
645 if (HwcConfig::getPipeline() == HWC_PIPE_LOOPBACK) {
646 char val[PROP_VALUE_LEN_MAX];
647 bool bVal = false;
648
649 if (HwcConfig::alwaysVdinLoopback()) {
650 /*get 3dmode status*/
651 bVal = !sys_get_bool_prop("vendor.hwc.postprocessor", true);
652 if (m3DMode != bVal) {
653 mDisplayRequests |= bVal ? rPostProcessorStop : rPostProcessorStart;
654 m3DMode = bVal;
655 if (m3DMode)
656 mKeyStoneMode = false;
657 }
658
659 if (!m3DMode) {
660 /*get keystone status*/
661 bVal = false;
662 if (sys_get_string_prop("persist.vendor.hwc.keystone", val) > 0 &&
663 strcmp(val, "0") != 0) {
664 bVal = true;
665 }
666 if (mKeyStoneMode != bVal) {
667 mDisplayRequests |= bVal ? rKeystoneEnable : rKeystoneDisable;
668 mKeyStoneMode = bVal;
669 }
670 }
671 } else {
672 bVal = false;
673 if (sys_get_string_prop("persist.vendor.hwc.keystone", val) > 0 &&
674 strcmp(val, "0") != 0) {
675 bVal = true;
676 }
677 if (mKeyStoneMode != bVal) {
678 mDisplayRequests |= bVal ?
679 (rPostProcessorStart | rKeystoneEnable) : rPostProcessorStop;
680 mKeyStoneMode = bVal;
681 }
682 }
683 }
684#endif
685 /*record and reset requests.*/
686 uint32_t request = mDisplayRequests;
687 mDisplayRequests = 0;
688 if (request > 0) {
689 MESON_LOGE("getDisplayRequest %x", request);
690 }
691 return request;
692}
693
694int32_t MesonHwc2::handleDisplayRequest(uint32_t request) {
695 mDisplayPipe->handleRequest(request);
696 return 0;
697}
698
699/**********************Internal Implement********************/
700
701class MesonHwc2Observer
702 : public Hwc2DisplayObserver, public HwcVsyncObserver{
703public:
704 MesonHwc2Observer(hwc2_display_t display, MesonHwc2 * hwc) {
705 mDispId = display;
706 mHwc = hwc;
707 }
708 ~MesonHwc2Observer() {
709 MESON_LOGD("MesonHwc2Observer disp(%d) destruct.", (int)mDispId);
710 }
711
712 void refresh() {
713 MESON_LOGD("Display (%d) ask for refresh.", (int)mDispId);
714 mHwc->refresh(mDispId);
715 }
716
717 void onVsync(int64_t timestamp) {
718 mHwc->onVsync(mDispId, timestamp);
719 }
720
721 void onHotplug(bool connected) {
722 mHwc->onHotplug(mDispId, connected);
723 }
724
725protected:
726 hwc2_display_t mDispId;
727 MesonHwc2 * mHwc;
728};
729
730MesonHwc2::MesonHwc2() {
731 mVirtualDisplayIds = 0;
732 mHotplugFn = NULL;
733 mHotplugData = NULL;
734 mRefreshFn = NULL;
735 mRefreshData = NULL;
736 mVsyncFn = NULL;
737 mVsyncData = NULL;
738 mDisplayRequests = 0;
739 initialize();
740}
741
742MesonHwc2::~MesonHwc2() {
743 mDisplays.clear();
744}
745
746void MesonHwc2::refresh(hwc2_display_t display) {
747 if (mRefreshFn) {
748 mRefreshFn(mRefreshData, display);
749 return;
750 }
751
752 MESON_LOGE("No refresh callback registered.");
753}
754
755void MesonHwc2::onVsync(hwc2_display_t display, int64_t timestamp) {
756 if (mVsyncFn) {
757 mVsyncFn(mVsyncData, display, timestamp);
758 return;
759 }
760
761 MESON_LOGE("No vsync callback registered.");
762}
763
764void MesonHwc2::onHotplug(hwc2_display_t display, bool connected) {
765 if (display == HWC_DISPLAY_PRIMARY && !HwcConfig::primaryHotplugEnabled()) {
766 MESON_LOGD("Primary display not support hotplug.");
767 return;
768 }
769
770 hwc2_connection_t connection =
771 connected ? HWC2_CONNECTION_CONNECTED : HWC2_CONNECTION_DISCONNECTED;
772
773 if (mHotplugFn) {
774 MESON_LOGD("On hotplug, Fn: %p, Data: %p, display: %d(%d), connection: %d",
775 mHotplugFn, mHotplugData, (int)display, HWC_DISPLAY_PRIMARY, connection);
776 mHotplugFn(mHotplugData, display, connection);
777 } else {
778 MESON_LOGE("No hotplug callback registered.");
779 }
780}
781
782int32_t MesonHwc2::captureDisplayScreen(buffer_handle_t hnd) {
783 GET_HWC_DISPLAY(0);
784 return hwcDisplay->captureDisplayScreen(hnd);
785}
786
787int32_t MesonHwc2::initialize() {
788 std::map<uint32_t, std::shared_ptr<HwcDisplay>> mhwcDisps;
789 mDisplayPipe = createDisplayPipe(HwcConfig::getPipeline());
790
791 for (uint32_t i = 0; i < HwcConfig::getDisplayNum(); i ++) {
792 /*create hwc2display*/
793 auto displayObserver = std::make_shared<MesonHwc2Observer>(i, this);
794 auto disp = std::make_shared<Hwc2Display>(displayObserver);
795 disp->initialize();
796 mDisplays.emplace(i, disp);
797 auto baseDisp = std::dynamic_pointer_cast<HwcDisplay>(disp);
798 mhwcDisps.emplace(i, baseDisp);
799 }
800
801 mDisplayPipe->init(mhwcDisps);
802 return HWC2_ERROR_NONE;
803}
804
805bool MesonHwc2::isDisplayValid(hwc2_display_t display) {
806 std::map<hwc2_display_t, std::shared_ptr<Hwc2Display>>::iterator it =
807 mDisplays.find(display);
808
809 if (it != mDisplays.end())
810 return true;
811
812 return false;
813}
814
815uint32_t MesonHwc2::getVirtualDisplayId() {
816 uint32_t idx;
817 for (idx = MESON_VIRTUAL_DISPLAY_ID_START; idx < 31; idx ++) {
818 if ((mVirtualDisplayIds & (1 << idx)) == 0) {
819 mVirtualDisplayIds |= (1 << idx);
820 MESON_LOGD("getVirtualDisplayId (%d) to (%x)", idx, mVirtualDisplayIds);
821 return idx;
822 }
823 }
824
825 MESON_LOGE("All virtual display id consumed.\n");
826 return 0;
827}
828
829void MesonHwc2::freeVirtualDisplayId(uint32_t id) {
830 mVirtualDisplayIds &= ~(1 << id);
831 MESON_LOGD("freeVirtualDisplayId (%d) to (%x)", id, mVirtualDisplayIds);
832}
833
834