summaryrefslogtreecommitdiff
path: root/libhwc2.1/ExynosHWC.cpp
diff options
context:
space:
mode:
authorHyunKyung Kim <hk310.kim@samsung.com>2019-08-12 15:27:36 +0900
committerHyunKyung Kim <hk310.kim@samsung.com>2019-09-18 19:34:02 +0900
commit6935a9b0ac01b978519d8d704dee3994440ff023 (patch)
treeb221bd0957f7ca7d936d598394dfc7dbf44ecdf7 /libhwc2.1/ExynosHWC.cpp
parentac1c0535583ce3eeb8f2b59431ebe510619c0416 (diff)
Add initial source code
Change-Id: I285a55c44c9fd5d3a8abaa781ef9dc8d9d39f53a Signed-off-by: HyunKyung Kim <hk310.kim@samsung.com>
Diffstat (limited to 'libhwc2.1/ExynosHWC.cpp')
-rw-r--r--libhwc2.1/ExynosHWC.cpp954
1 files changed, 954 insertions, 0 deletions
diff --git a/libhwc2.1/ExynosHWC.cpp b/libhwc2.1/ExynosHWC.cpp
new file mode 100644
index 0000000..f10db57
--- /dev/null
+++ b/libhwc2.1/ExynosHWC.cpp
@@ -0,0 +1,954 @@
+/*
+ * Copyright (C) 2012 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+#define ATRACE_TAG ATRACE_TAG_GRAPHICS
+
+#include <hardware/hardware.h>
+#include <utils/Errors.h>
+#include <utils/Trace.h>
+#include <log/log.h>
+#include <sys/stat.h>
+
+#include "ExynosHWC.h"
+#include "ExynosHWCModule.h"
+#include "ExynosHWCService.h"
+#include "ExynosDisplay.h"
+#include "ExynosLayer.h"
+#include "ExynosExternalDisplayModule.h"
+
+class ExynosHWCService;
+
+using namespace android;
+
+uint32_t hwcApiVersion(const hwc_composer_device_1_t* hwc) {
+ uint32_t hwcVersion = hwc->common.version;
+ return hwcVersion & HARDWARE_API_VERSION_2_MAJ_MIN_MASK;
+}
+
+uint32_t hwcHeaderVersion(const hwc_composer_device_1_t* hwc) {
+ uint32_t hwcVersion = hwc->common.version;
+ return hwcVersion & HARDWARE_API_VERSION_2_HEADER_MASK;
+}
+
+bool hwcHasApiVersion(const hwc_composer_device_1_t* hwc, uint32_t version)
+{
+ return (hwcApiVersion(hwc) >= (version & HARDWARE_API_VERSION_2_MAJ_MIN_MASK));
+}
+
+/**************************************************************************************
+ * HWC 2.x APIs
+ * ************************************************************************************/
+ExynosDevice *g_exynosDevice = NULL;
+
+hwc2_function_pointer_t exynos_function_pointer[] =
+{
+ NULL, //HWC2_FUNCTION_INVAILD
+ reinterpret_cast<hwc2_function_pointer_t>(exynos_acceptDisplayChanges), //HWC2_FUNCTION_ACCEPT_DISPLAY_CHANGES
+ reinterpret_cast<hwc2_function_pointer_t>(exynos_createLayer), //HWC2_FUNCTION_CREATE_LAYER
+ reinterpret_cast<hwc2_function_pointer_t>(exynos_createVirtualDisplay), //HWC2_FUNCTION_CREATE_VIRTUAL_DISPLAY
+ reinterpret_cast<hwc2_function_pointer_t>(exynos_destroyLayer), //HWC2_FUNCTION_DESTROY_LAYER
+ reinterpret_cast<hwc2_function_pointer_t>(exynos_destroyVirtualDisplay), //HWC2_FUNCTION_DESTROY_VIRTUAL_DISPLAY
+ reinterpret_cast<hwc2_function_pointer_t>(exynos_dump), //HWC2_FUNCTION_DUMP
+ reinterpret_cast<hwc2_function_pointer_t>(exynos_getActiveConfig), //HWC2_FUNCTION_GET_ACTIVE_CONFIG
+ reinterpret_cast<hwc2_function_pointer_t>(exynos_getChangedCompositionTypes), //HWC2_FUNCTION_GET_CHANGED_COMPOSITION_TYPES
+ reinterpret_cast<hwc2_function_pointer_t>(exynos_getClientTargetSupport), //HWC2_FUNCTION_GET_CLIENT_TARGET_SUPPORT
+ reinterpret_cast<hwc2_function_pointer_t>(exynos_getColorModes), //HWC2_FUNCTION_GET_COLOR_MODES
+ reinterpret_cast<hwc2_function_pointer_t>(exynos_getDisplayAttribute), //HWC2_FUNCTION_GET_DISPLAY_ATTRIBUTE
+ reinterpret_cast<hwc2_function_pointer_t>(exynos_getDisplayConfigs), //HWC2_FUNCTION_GET_DISPLAY_CONFIGS
+ reinterpret_cast<hwc2_function_pointer_t>(exynos_getDisplayName), //HWC2_FUNCTION_GET_DISPLAY_NAME
+ reinterpret_cast<hwc2_function_pointer_t>(exynos_getDisplayRequests), //HWC2_FUNCTION_GET_DISPLAY_REQUESTS
+ reinterpret_cast<hwc2_function_pointer_t>(exynos_getDisplayType), //HWC2_FUNCTION_GET_DISPLAY_TYPE
+ reinterpret_cast<hwc2_function_pointer_t>(exynos_getDozeSupport), //HWC2_FUNCTION_GET_DOZE_SUPPORT
+ reinterpret_cast<hwc2_function_pointer_t>(exynos_getHdrCapabilities), //HWC2_FUNCTION_GET_HDR_CAPABILITIES
+ reinterpret_cast<hwc2_function_pointer_t>(exynos_getMaxVirtualDisplayCount), //HWC2_FUNCTION_GET_MAX_VIRTUAL_DISPLAY_COUNT
+ reinterpret_cast<hwc2_function_pointer_t>(exynos_getReleaseFences), //HWC2_FUNCTION_GET_RELEASE_FENCES
+ reinterpret_cast<hwc2_function_pointer_t>(exynos_presentDisplay), //HWC2_FUNCTION_PRESENT_DISPLAY
+ reinterpret_cast<hwc2_function_pointer_t>(exynos_registerCallback), //HWC2_FUNCTION_REGISTER_CALLBACK
+ reinterpret_cast<hwc2_function_pointer_t>(exynos_setActiveConfig), //HWC2_FUNCTION_SET_ACTIVE_CONFIG
+ reinterpret_cast<hwc2_function_pointer_t>(exynos_setClientTarget), //HWC2_FUNCTION_SET_CLIENT_TARGET
+ reinterpret_cast<hwc2_function_pointer_t>(exynos_setColorMode), //HWC2_FUNCTION_SET_COLOR_MODE
+ reinterpret_cast<hwc2_function_pointer_t>(exynos_setColorTransform), //HWC2_FUNCTION_SET_COLOR_TRANSFORM
+ reinterpret_cast<hwc2_function_pointer_t>(exynos_setCursorPosition), //HWC2_FUNCTION_SET_CURSOR_POSITION
+ reinterpret_cast<hwc2_function_pointer_t>(exynos_setLayerBlendMode), //HWC2_FUNCTION_SET_LAYER_BLEND_MODE
+ reinterpret_cast<hwc2_function_pointer_t>(exynos_setLayerBuffer), //HWC2_FUNCTION_SET_LAYER_BUFFER
+ reinterpret_cast<hwc2_function_pointer_t>(exynos_setLayerColor), //HWC2_FUNCTION_SET_LAYER_COLOR
+ reinterpret_cast<hwc2_function_pointer_t>(exynos_setLayerCompositionType), //HWC2_FUNCTION_SET_LAYER_COMPOSITION_TYPE
+ reinterpret_cast<hwc2_function_pointer_t>(exynos_setLayerDataspace), //HWC2_FUNCTION_SET_LAYER_DATASPACE
+ reinterpret_cast<hwc2_function_pointer_t>(exynos_setLayerDisplayFrame), //HWC2_FUNCTION_SET_LAYER_DISPLAY_FRAME
+ reinterpret_cast<hwc2_function_pointer_t>(exynos_setLayerPlaneAlpha), //HWC2_FUNCTION_SET_LAYER_PLANE_ALPHA
+ reinterpret_cast<hwc2_function_pointer_t>(exynos_setLayerSidebandStream), //HWC2_FUNCTION_SET_LAYER_SIDEBAND_STREAM
+ reinterpret_cast<hwc2_function_pointer_t>(exynos_setLayerSourceCrop), //HWC2_FUNCTION_SET_LAYER_SOURCE_CROP
+ reinterpret_cast<hwc2_function_pointer_t>(exynos_setLayerSurfaceDamage), //HWC2_FUNCTION_SET_LAYER_SURFACE_DAMAGE
+ reinterpret_cast<hwc2_function_pointer_t>(exynos_setLayerTransform), //HWC2_FUNCTION_SET_LAYER_TRANSFORM
+ reinterpret_cast<hwc2_function_pointer_t>(exynos_setLayerVisibleRegion), //HWC2_FUNCTION_SET_LAYER_VISIBLE_REGION
+ reinterpret_cast<hwc2_function_pointer_t>(exynos_setLayerZOrder), //HWC2_FUNCTION_SET_LAYER_Z_ORDER
+ reinterpret_cast<hwc2_function_pointer_t>(exynos_setOutputBuffer), //HWC2_FUNCTION_SET_OUTPUT_BUFFER
+ reinterpret_cast<hwc2_function_pointer_t>(exynos_setPowerMode), //HWC2_FUNCTION_SET_POWER_MODE
+ reinterpret_cast<hwc2_function_pointer_t>(exynos_setVsyncEnabled), //HWC2_FUNCTION_SET_VSYNC_ENABLED
+ reinterpret_cast<hwc2_function_pointer_t>(exynos_validateDisplay), //HWC2_FUNCTION_VALIDATE_DISPLAY
+ reinterpret_cast<hwc2_function_pointer_t>(NULL), //HWC2_FUNCTION_SET_LAYER_FLOAT_COLOR
+ reinterpret_cast<hwc2_function_pointer_t>(exynos_setLayerPerFrameMetadata), //HWC2_FUNCTION_SET_LAYER_PER_FRAME_METADATA
+ reinterpret_cast<hwc2_function_pointer_t>(exynos_getPerFrameMetadataKeys), //HWC2_FUNCTION_GET_PER_FRAME_METADATA_KEYS
+};
+
+inline ExynosDevice* checkDevice(hwc2_device_t *dev)
+{
+ struct exynos_hwc2_device_t *pdev = (struct exynos_hwc2_device_t *)dev;
+ ExynosDevice *exynosDevice = pdev->device;
+ if ((g_exynosDevice == NULL) || (exynosDevice != g_exynosDevice)) {
+ ALOGE("device pointer is not valid (%p, %p)", exynosDevice, g_exynosDevice);
+ return NULL;
+ }
+
+ return exynosDevice;
+}
+
+inline ExynosDisplay* checkDisplay(ExynosDevice *exynosDevice, hwc2_display_t display)
+{
+ ExynosDisplay *exynosDisplay = exynosDevice->getDisplay((uint32_t)display);
+ if (exynosDisplay == NULL) {
+ ALOGE("exynosDisplay is NULL");
+ return NULL;
+ }
+
+ return exynosDisplay;
+}
+
+inline ExynosLayer* checkLayer(ExynosDisplay *exynosDisplay, hwc2_layer_t layer)
+{
+ ExynosLayer *exynosLayer = exynosDisplay->checkLayer(layer);
+ if (exynosLayer == NULL) {
+ ALOGE("exynosLayer is NULL");
+ return NULL;
+ }
+
+ return exynosLayer;
+}
+
+hwc2_function_pointer_t exynos_getFunction(struct hwc2_device *dev,
+ int32_t descriptor)
+{
+ ExynosDevice *exynosDevice = checkDevice(dev);
+ if (!exynosDevice)
+ return NULL;
+
+ if (descriptor <= HWC2_FUNCTION_INVALID || descriptor > HWC2_FUNCTION_GET_PER_FRAME_METADATA_KEYS)
+ return NULL;
+ return exynos_function_pointer[descriptor];
+}
+
+void exynos_getCapabilities(struct hwc2_device *dev, uint32_t *outCount, int32_t *outCapabilities)
+{
+ ExynosDevice *exynosDevice = checkDevice(dev);
+
+ if (!exynosDevice)
+ *outCapabilities = 0;
+ else
+ return exynosDevice->getCapabilities(outCount, outCapabilities);
+}
+
+void exynos_dump(hwc2_device_t *dev, uint32_t *outSize, char *outBuffer)
+{
+ ExynosDevice *exynosDevice = checkDevice(dev);
+
+ if (exynosDevice)
+ return exynosDevice->dump(outSize, outBuffer);
+}
+
+int32_t exynos_acceptDisplayChanges(hwc2_device_t *dev, hwc2_display_t display)
+{
+ ExynosDevice *exynosDevice = checkDevice(dev);
+
+ if (exynosDevice) {
+ ExynosDisplay *exynosDisplay = checkDisplay(exynosDevice, (uint32_t)display);
+ if (exynosDisplay)
+ return exynosDisplay->acceptDisplayChanges();
+ }
+
+ return HWC2_ERROR_BAD_DISPLAY;
+}
+
+int32_t exynos_createLayer(hwc2_device_t *dev,
+ hwc2_display_t display, hwc2_layer_t *outLayer)
+{
+ ExynosDevice *exynosDevice = checkDevice(dev);
+
+ if (exynosDevice) {
+ ExynosDisplay *exynosDisplay = checkDisplay(exynosDevice, display);
+ if (exynosDisplay)
+ return exynosDisplay->createLayer(outLayer);
+ }
+
+ return HWC2_ERROR_BAD_DISPLAY;
+}
+
+int32_t exynos_createVirtualDisplay(hwc2_device_t *dev, uint32_t width, uint32_t height,
+ int32_t *format, hwc2_display_t *outDisplay)
+{
+ ExynosDevice *exynosDevice = checkDevice(dev);
+ *outDisplay = HWC_DISPLAY_VIRTUAL;
+
+ if (exynosDevice) {
+ ExynosDisplay *exynosDisplay = checkDisplay(exynosDevice, *outDisplay);
+ if (exynosDisplay)
+ return exynosDevice->createVirtualDisplay(width, height, format, exynosDisplay);
+ }
+
+ return HWC2_ERROR_BAD_PARAMETER;
+}
+
+int32_t exynos_destroyLayer(hwc2_device_t *dev, hwc2_display_t display,
+ hwc2_layer_t layer)
+{
+ ExynosDevice *exynosDevice = checkDevice(dev);
+
+ if (exynosDevice) {
+ ExynosDisplay *exynosDisplay = checkDisplay(exynosDevice, display);
+ if (exynosDisplay) {
+ ExynosLayer *exynosLayer = checkLayer(exynosDisplay, layer);
+ if (exynosLayer)
+ return exynosDisplay->destroyLayer((hwc2_layer_t)exynosLayer);
+ }
+ }
+
+ return HWC2_ERROR_BAD_DISPLAY;
+}
+
+int32_t exynos_destroyVirtualDisplay(hwc2_device_t* dev, hwc2_display_t display)
+{
+ ExynosDevice *exynosDevice = checkDevice(dev);
+
+ if (exynosDevice) {
+ ExynosDisplay *exynosDisplay = checkDisplay(exynosDevice, display);
+ if (exynosDisplay) {
+ exynosDisplay->destroyLayers();
+ return exynosDevice->destroyVirtualDisplay(exynosDisplay);
+ }
+ }
+
+ return HWC2_ERROR_BAD_DISPLAY;
+}
+
+int32_t exynos_getActiveConfig(hwc2_device_t *dev, hwc2_display_t display,
+ hwc2_config_t* outConfig)
+{
+ ExynosDevice *exynosDevice = checkDevice(dev);
+
+ if (exynosDevice) {
+ ExynosDisplay *exynosDisplay = checkDisplay(exynosDevice, display);
+ if (exynosDisplay)
+ return exynosDisplay->getActiveConfig(outConfig);
+ }
+
+ return HWC2_ERROR_BAD_DISPLAY;
+}
+
+int32_t exynos_getChangedCompositionTypes(hwc2_device_t *dev, hwc2_display_t display,
+ uint32_t* outNumElements, hwc2_layer_t* outLayers,
+ int32_t* /*hwc2_composition_t*/ outTypes)
+{
+ ExynosDevice *exynosDevice = checkDevice(dev);
+
+ if (exynosDevice) {
+ ExynosDisplay *exynosDisplay = checkDisplay(exynosDevice, display);
+ if (exynosDisplay)
+ return exynosDisplay->getChangedCompositionTypes(outNumElements, outLayers, outTypes);
+ }
+
+ return HWC2_ERROR_BAD_DISPLAY;
+}
+
+int32_t exynos_getClientTargetSupport(hwc2_device_t *dev, hwc2_display_t display, uint32_t width,
+ uint32_t height, int32_t format, int32_t dataSpace)
+{
+ ExynosDevice *exynosDevice = checkDevice(dev);
+
+ if (exynosDevice) {
+ ExynosDisplay *exynosDisplay = checkDisplay(exynosDevice, display);
+ if (exynosDisplay)
+ return exynosDisplay->getClientTargetSupport(width, height, format, dataSpace);
+ }
+
+ return HWC2_ERROR_BAD_DISPLAY;
+}
+
+int32_t exynos_getColorModes(hwc2_device_t *dev, hwc2_display_t display, uint32_t* outNumModes,
+ int32_t* outModes)
+{
+ ExynosDevice *exynosDevice = checkDevice(dev);
+
+ if (exynosDevice) {
+ ExynosDisplay *exynosDisplay = checkDisplay(exynosDevice, display);
+ if (exynosDisplay)
+ return exynosDisplay->getColorModes(outNumModes, outModes);
+ }
+
+ return HWC2_ERROR_BAD_DISPLAY;
+}
+
+int32_t exynos_getDisplayAttribute(hwc2_device_t *dev, hwc2_display_t display,
+ hwc2_config_t config, int32_t /*hwc2_attribute_t*/ attribute, int32_t* outValue)
+{
+ ExynosDevice *exynosDevice = checkDevice(dev);
+
+ if (exynosDevice) {
+ ExynosDisplay *exynosDisplay = checkDisplay(exynosDevice, display);
+ if (exynosDisplay)
+ return exynosDisplay->getDisplayAttribute(config, attribute, outValue);
+ }
+
+ return HWC2_ERROR_BAD_DISPLAY;
+}
+
+int32_t exynos_getDisplayConfigs(hwc2_device_t *dev, hwc2_display_t display,
+ uint32_t* outNumConfigs, hwc2_config_t* outConfigs)
+{
+ ExynosDevice *exynosDevice = checkDevice(dev);
+
+ if (exynosDevice) {
+ ExynosDisplay *exynosDisplay = checkDisplay(exynosDevice, display);
+ if (exynosDisplay)
+ return exynosDisplay->getDisplayConfigs(outNumConfigs, outConfigs);
+ }
+
+ return HWC2_ERROR_BAD_DISPLAY;
+}
+
+int32_t exynos_getDisplayName(hwc2_device_t *dev, hwc2_display_t display,
+ uint32_t* outSize, char* outName)
+{
+ ExynosDevice *exynosDevice = checkDevice(dev);
+
+ if (exynosDevice) {
+ ExynosDisplay *exynosDisplay = checkDisplay(exynosDevice, display);
+ if (exynosDisplay)
+ return exynosDisplay->getDisplayName(outSize, outName);
+ }
+
+ return HWC2_ERROR_BAD_DISPLAY;
+}
+
+int32_t exynos_getDisplayRequests(hwc2_device_t *dev, hwc2_display_t display,
+ int32_t* /*hwc2_display_request_t*/ outDisplayRequests,
+ uint32_t* outNumElements, hwc2_layer_t* outLayers,
+ int32_t* /*hwc2_layer_request_t*/ outLayerRequests)
+{
+ ExynosDevice *exynosDevice = checkDevice(dev);
+
+ if (exynosDevice) {
+ ExynosDisplay *exynosDisplay = checkDisplay(exynosDevice, display);
+ if (exynosDisplay)
+ return exynosDisplay->getDisplayRequests(outDisplayRequests, outNumElements, outLayers, outLayerRequests);
+ }
+
+ return HWC2_ERROR_BAD_DISPLAY;
+}
+
+int32_t exynos_getDisplayType(hwc2_device_t *dev, hwc2_display_t display,
+ int32_t* /*hwc2_display_type_t*/ outType)
+{
+ ExynosDevice *exynosDevice = checkDevice(dev);
+
+ if (exynosDevice) {
+ ExynosDisplay *exynosDisplay = checkDisplay(exynosDevice, display);
+ if (exynosDisplay)
+ return exynosDisplay->getDisplayType(outType);
+ }
+
+ return HWC2_ERROR_BAD_DISPLAY;
+}
+
+int32_t exynos_getDozeSupport(hwc2_device_t *dev, hwc2_display_t display,
+ int32_t* outSupport)
+{
+ ExynosDevice *exynosDevice = checkDevice(dev);
+
+ if (exynosDevice) {
+ ExynosDisplay *exynosDisplay = checkDisplay(exynosDevice, display);
+ if (exynosDisplay)
+ return exynosDisplay->getDozeSupport(outSupport);
+ }
+
+ return HWC2_ERROR_BAD_DISPLAY;
+}
+
+int32_t exynos_getHdrCapabilities(hwc2_device_t *dev, hwc2_display_t display,
+ uint32_t* __unused outNumTypes,
+ int32_t* __unused outTypes, float* __unused outMaxLuminance,
+ float* __unused outMaxAverageLuminance, float* __unused outMinLuminance)
+{
+ ExynosDevice *exynosDevice = checkDevice(dev);
+
+ if (exynosDevice) {
+ ExynosDisplay *exynosDisplay = checkDisplay(exynosDevice, display);
+ if (exynosDisplay) {
+ return exynosDisplay->getHdrCapabilities(outNumTypes, outTypes, outMaxLuminance,
+ outMaxAverageLuminance, outMinLuminance);
+ return 0;
+ }
+ }
+
+ return HWC2_ERROR_BAD_DISPLAY;
+}
+
+int32_t exynos_getMaxVirtualDisplayCount(hwc2_device_t* dev)
+{
+ ExynosDevice *exynosDevice = checkDevice(dev);
+
+ if (exynosDevice)
+ return exynosDevice->getMaxVirtualDisplayCount();
+ else
+ return HWC2_ERROR_BAD_PARAMETER;
+}
+
+int32_t exynos_getReleaseFences(hwc2_device_t *dev, hwc2_display_t display,
+ uint32_t* outNumElements, hwc2_layer_t* outLayers, int32_t* outFences)
+{
+ ExynosDevice *exynosDevice = checkDevice(dev);
+
+ if (exynosDevice) {
+ ExynosDisplay *exynosDisplay = checkDisplay(exynosDevice, display);
+ if (exynosDisplay)
+ return exynosDisplay->getReleaseFences(outNumElements, outLayers, outFences);
+ }
+
+ return HWC2_ERROR_BAD_DISPLAY;
+}
+
+int32_t exynos_presentDisplay(hwc2_device_t *dev, hwc2_display_t display,
+ int32_t* outRetireFence)
+{
+ ExynosDevice *exynosDevice = checkDevice(dev);
+
+ if (exynosDevice) {
+ ExynosDisplay *exynosDisplay = checkDisplay(exynosDevice, display);
+ if (exynosDisplay)
+ return exynosDisplay->presentDisplay(outRetireFence);
+ }
+
+ return HWC2_ERROR_BAD_DISPLAY;
+}
+
+int32_t exynos_registerCallback(hwc2_device_t* dev,
+ int32_t /*hwc2_callback_descriptor_t*/ descriptor,
+ hwc2_callback_data_t callbackData, hwc2_function_pointer_t pointer)
+{
+ int32_t ret = 0;
+ struct exynos_hwc2_device_t *pdev = (struct exynos_hwc2_device_t *)dev;
+ ExynosDevice *exynosDevice = pdev->device;
+ if (exynosDevice == NULL)
+ {
+ ALOGE("%s:: descriptor(%d), exynosDevice(%p), pointer(%p)",
+ __func__, descriptor, exynosDevice, pointer);
+ return HWC2_ERROR_BAD_PARAMETER;
+ }
+
+ switch (descriptor) {
+ case HWC2_CALLBACK_HOTPLUG:
+ case HWC2_CALLBACK_REFRESH:
+ case HWC2_CALLBACK_VSYNC:
+ ret = exynosDevice->registerCallback(descriptor, callbackData, pointer);
+ return ret;
+ default:
+ return HWC2_ERROR_BAD_PARAMETER;
+ }
+
+ return HWC2_ERROR_NONE;
+}
+
+int32_t exynos_setActiveConfig(hwc2_device_t *dev, hwc2_display_t display,
+ hwc2_config_t config)
+{
+ ExynosDevice *exynosDevice = checkDevice(dev);
+
+ if (exynosDevice) {
+ ExynosDisplay *exynosDisplay = checkDisplay(exynosDevice, display);
+ if (exynosDisplay)
+ return exynosDisplay->setActiveConfig(config);
+ }
+
+ return HWC2_ERROR_BAD_DISPLAY;
+}
+
+int32_t exynos_setClientTarget(hwc2_device_t *dev, hwc2_display_t display,
+ buffer_handle_t target, int32_t acquireFence,
+ int32_t /*android_dataspace_t*/ dataspace, hwc_region_t __unused damage)
+{
+ ExynosDevice *exynosDevice = checkDevice(dev);
+
+ if (exynosDevice) {
+ ExynosDisplay *exynosDisplay = checkDisplay(exynosDevice, display);
+ if (exynosDisplay)
+ return exynosDisplay->setClientTarget(target, acquireFence, dataspace);
+ }
+
+ return HWC2_ERROR_BAD_DISPLAY;
+}
+
+int32_t exynos_setColorMode(hwc2_device_t *dev, hwc2_display_t display, int32_t mode)
+{
+ ExynosDevice *exynosDevice = checkDevice(dev);
+
+ if (exynosDevice) {
+ ExynosDisplay *exynosDisplay = checkDisplay(exynosDevice, display);
+ if (exynosDisplay)
+ return exynosDisplay->setColorMode(mode);
+ }
+
+ return HWC2_ERROR_BAD_DISPLAY;
+}
+
+int32_t exynos_setColorTransform(hwc2_device_t *dev, hwc2_display_t display,
+ const float* matrix, int32_t hint)
+{
+ ExynosDevice *exynosDevice = checkDevice(dev);
+
+ if (exynosDevice) {
+ ExynosDisplay *exynosDisplay = checkDisplay(exynosDevice, display);
+ if (exynosDisplay)
+ return exynosDisplay->setColorTransform(matrix, hint);
+ }
+
+ return HWC2_ERROR_BAD_DISPLAY;
+}
+
+int32_t exynos_setCursorPosition(hwc2_device_t *dev, hwc2_display_t display,
+ hwc2_layer_t layer, int32_t x, int32_t y)
+{
+ ExynosDevice *exynosDevice = checkDevice(dev);
+
+ if (exynosDevice) {
+ ExynosDisplay *exynosDisplay = checkDisplay(exynosDevice, display);
+ if (exynosDisplay) {
+ ExynosLayer *exynosLayer = checkLayer(exynosDisplay, layer);
+ if (exynosLayer)
+ return exynosLayer->setCursorPosition(x, y);
+ }
+ }
+
+ return HWC2_ERROR_BAD_LAYER;
+}
+
+int32_t exynos_setLayerBlendMode(hwc2_device_t *dev, hwc2_display_t display,
+ hwc2_layer_t __unused layer, int32_t /*hwc2_blend_mode_t*/ __unused mode)
+{
+ ExynosDevice *exynosDevice = checkDevice(dev);
+
+ if (exynosDevice) {
+ ExynosDisplay *exynosDisplay = checkDisplay(exynosDevice, display);
+ if (exynosDisplay) {
+ ExynosLayer *exynosLayer = checkLayer(exynosDisplay, layer);
+ if (exynosLayer)
+ return exynosLayer->setLayerBlendMode(mode);
+ }
+ }
+
+ return HWC2_ERROR_BAD_LAYER;
+}
+
+int32_t exynos_setLayerBuffer(hwc2_device_t *dev, hwc2_display_t display,
+ hwc2_layer_t layer, buffer_handle_t buffer, int32_t acquireFence)
+{
+ ExynosDevice *exynosDevice = checkDevice(dev);
+
+ if (exynosDevice) {
+ ExynosDisplay *exynosDisplay = checkDisplay(exynosDevice, display);
+ if (exynosDisplay) {
+ Mutex::Autolock lock(exynosDisplay->mDisplayMutex);
+ ExynosLayer *exynosLayer = checkLayer(exynosDisplay, layer);
+ if (exynosLayer)
+ return exynosLayer->setLayerBuffer(buffer, acquireFence);
+ }
+ }
+
+ return HWC2_ERROR_BAD_LAYER;
+}
+
+int32_t exynos_setLayerColor(hwc2_device_t *dev, hwc2_display_t display,
+ hwc2_layer_t layer, hwc_color_t color)
+{
+ ExynosDevice *exynosDevice = checkDevice(dev);
+
+ if (exynosDevice) {
+ ExynosDisplay *exynosDisplay = checkDisplay(exynosDevice, display);
+ if (exynosDisplay) {
+ ExynosLayer *exynosLayer = checkLayer(exynosDisplay, layer);
+ if (exynosLayer)
+ return exynosLayer->setLayerColor(color);
+ }
+ }
+
+ return HWC2_ERROR_BAD_LAYER;
+}
+
+int32_t exynos_setLayerCompositionType(hwc2_device_t *dev, hwc2_display_t display,
+ hwc2_layer_t layer, int32_t /*hwc2_composition_t*/ type)
+{
+ ExynosDevice *exynosDevice = checkDevice(dev);
+
+ if (exynosDevice) {
+ ExynosDisplay *exynosDisplay = checkDisplay(exynosDevice, display);
+ if (exynosDisplay) {
+ ExynosLayer *exynosLayer = checkLayer(exynosDisplay, layer);
+ if (exynosLayer)
+ return exynosLayer->setLayerCompositionType(type);
+ }
+ }
+
+ return HWC2_ERROR_BAD_LAYER;
+}
+
+int32_t exynos_setLayerDataspace(hwc2_device_t *dev, hwc2_display_t display, hwc2_layer_t layer, int32_t dataspace)
+{
+ ExynosDevice *exynosDevice = checkDevice(dev);
+
+ if (exynosDevice) {
+ ExynosDisplay *exynosDisplay = checkDisplay(exynosDevice, display);
+ if (exynosDisplay) {
+ Mutex::Autolock lock(exynosDisplay->mDisplayMutex);
+ ExynosLayer *exynosLayer = checkLayer(exynosDisplay, layer);
+ if (exynosLayer)
+ return exynosLayer->setLayerDataspace(dataspace);
+ }
+ }
+
+ return HWC2_ERROR_BAD_LAYER;
+}
+
+int32_t exynos_setLayerDisplayFrame(hwc2_device_t *dev, hwc2_display_t __unused display,
+ hwc2_layer_t __unused layer, hwc_rect_t __unused frame)
+{
+ ExynosDevice *exynosDevice = checkDevice(dev);
+
+ if (exynosDevice) {
+ ExynosDisplay *exynosDisplay = checkDisplay(exynosDevice, display);
+ if (exynosDisplay) {
+ ExynosLayer *exynosLayer = checkLayer(exynosDisplay, layer);
+ if (exynosLayer)
+ return exynosLayer->setLayerDisplayFrame(frame);
+ }
+ }
+
+ return HWC2_ERROR_BAD_LAYER;
+}
+
+int32_t exynos_setLayerPlaneAlpha(hwc2_device_t __unused *dev, hwc2_display_t __unused display,
+ hwc2_layer_t __unused layer, float __unused alpha)
+{
+ ExynosDevice *exynosDevice = checkDevice(dev);
+
+ if (exynosDevice) {
+ ExynosDisplay *exynosDisplay = checkDisplay(exynosDevice, display);
+ if (exynosDisplay) {
+ ExynosLayer *exynosLayer = checkLayer(exynosDisplay, layer);
+ if (exynosLayer)
+ return exynosLayer->setLayerPlaneAlpha(alpha);
+ }
+ }
+
+ return HWC2_ERROR_BAD_LAYER;
+}
+
+int32_t exynos_setLayerSidebandStream(hwc2_device_t __unused *dev, hwc2_display_t __unused display,
+ hwc2_layer_t __unused layer, const native_handle_t* __unused stream)
+{
+ ALOGE("%s:: unsuported api", __func__);
+ return HWC2_ERROR_NONE;
+}
+
+int32_t exynos_setLayerSourceCrop(hwc2_device_t __unused *dev, hwc2_display_t __unused display,
+ hwc2_layer_t __unused layer, hwc_frect_t __unused crop)
+{
+ ExynosDevice *exynosDevice = checkDevice(dev);
+
+ if (exynosDevice) {
+ ExynosDisplay *exynosDisplay = checkDisplay(exynosDevice, display);
+ if (exynosDisplay) {
+ ExynosLayer *exynosLayer = checkLayer(exynosDisplay, layer);
+ if (exynosLayer)
+ return exynosLayer->setLayerSourceCrop(crop);
+ }
+ }
+
+ return HWC2_ERROR_BAD_LAYER;
+}
+
+int32_t exynos_setLayerSurfaceDamage(hwc2_device_t __unused *dev, hwc2_display_t __unused display,
+ hwc2_layer_t __unused layer, hwc_region_t __unused damage)
+{
+ ExynosDevice *exynosDevice = checkDevice(dev);
+
+ if (exynosDevice) {
+ ExynosDisplay *exynosDisplay = checkDisplay(exynosDevice, display);
+ if (exynosDisplay) {
+ ExynosLayer *exynosLayer = checkLayer(exynosDisplay, layer);
+ if (exynosLayer)
+ return exynosLayer->setLayerSurfaceDamage(damage);
+ }
+ }
+
+ return HWC2_ERROR_BAD_LAYER;
+}
+
+int32_t exynos_setLayerTransform(hwc2_device_t *dev, hwc2_display_t __unused display,
+ hwc2_layer_t __unused layer, int32_t /*hwc_transform_t*/ __unused transform)
+{
+ ExynosDevice *exynosDevice = checkDevice(dev);
+
+ if (exynosDevice) {
+ ExynosDisplay *exynosDisplay = checkDisplay(exynosDevice, display);
+ if (exynosDisplay) {
+ ExynosLayer *exynosLayer = checkLayer(exynosDisplay, layer);
+ if (exynosLayer)
+ return exynosLayer->setLayerTransform(transform);
+ }
+ }
+
+ return HWC2_ERROR_BAD_LAYER;
+}
+
+int32_t exynos_setLayerVisibleRegion(hwc2_device_t *dev, hwc2_display_t __unused display,
+ hwc2_layer_t __unused layer, hwc_region_t __unused visible)
+{
+ ExynosDevice *exynosDevice = checkDevice(dev);
+
+ if (exynosDevice) {
+ ExynosDisplay *exynosDisplay = checkDisplay(exynosDevice, display);
+ if (exynosDisplay) {
+ ExynosLayer *exynosLayer = checkLayer(exynosDisplay, layer);
+ if (exynosLayer)
+ return exynosLayer->setLayerVisibleRegion(visible);
+ }
+ }
+
+ return HWC2_ERROR_BAD_LAYER;
+}
+
+int32_t exynos_setLayerZOrder(hwc2_device_t *dev, hwc2_display_t display,
+ hwc2_layer_t layer, uint32_t z)
+{
+ ExynosDevice *exynosDevice = checkDevice(dev);
+
+ if (exynosDevice) {
+ ExynosDisplay *exynosDisplay = checkDisplay(exynosDevice, display);
+ if (exynosDisplay) {
+ ExynosLayer *exynosLayer = checkLayer(exynosDisplay, layer);
+ if (exynosLayer)
+ return exynosLayer->setLayerZOrder(z);
+ }
+ }
+
+ return HWC2_ERROR_BAD_LAYER;
+}
+
+int32_t exynos_setOutputBuffer(hwc2_device_t *dev, hwc2_display_t display,
+ buffer_handle_t buffer, int32_t releaseFence)
+{
+ ExynosDevice *exynosDevice = checkDevice(dev);
+
+ if (exynosDevice) {
+ ExynosDisplay *exynosDisplay = checkDisplay(exynosDevice, display);
+ if (exynosDisplay)
+ return exynosDisplay->setOutputBuffer(buffer, releaseFence);
+ }
+
+ return HWC2_ERROR_BAD_DISPLAY;
+}
+
+int32_t exynos_setPowerMode(hwc2_device_t *dev, hwc2_display_t __unused display,
+ int32_t /*hwc2_power_mode_t*/ __unused mode)
+{
+ ExynosDevice *exynosDevice = checkDevice(dev);
+
+ if (exynosDevice) {
+ ExynosDisplay *exynosDisplay = checkDisplay(exynosDevice, display);
+ if (exynosDisplay) {
+ return exynosDisplay->setPowerMode(mode);
+ }
+ }
+
+ return HWC2_ERROR_BAD_DISPLAY;
+}
+
+int32_t exynos_setVsyncEnabled(hwc2_device_t *dev, hwc2_display_t __unused display,
+ int32_t /*hwc2_vsync_t*/ __unused enabled)
+{
+ ExynosDevice *exynosDevice = checkDevice(dev);
+
+ if (exynosDevice) {
+ ExynosDisplay *exynosDisplay = checkDisplay(exynosDevice, display);
+ if (exynosDisplay)
+ return exynosDisplay->setVsyncEnabled(enabled);
+ }
+
+ return HWC2_ERROR_BAD_DISPLAY;
+}
+
+int32_t exynos_validateDisplay(hwc2_device_t __unused *dev, hwc2_display_t __unused display,
+ uint32_t* __unused outNumTypes, uint32_t* __unused outNumRequests)
+{
+ ExynosDevice *exynosDevice = checkDevice(dev);
+
+ if (exynosDevice) {
+ ExynosDisplay *exynosDisplay = checkDisplay(exynosDevice, display);
+ if (exynosDisplay)
+ return exynosDisplay->validateDisplay(outNumTypes, outNumRequests);
+ }
+
+ return HWC2_ERROR_BAD_DISPLAY;
+}
+
+int32_t exynos_setLayerPerFrameMetadata(hwc2_device_t *dev, hwc2_display_t display,
+ hwc2_layer_t layer, uint32_t numElements,
+ const int32_t* /*hw2_per_frame_metadata_key_t*/ keys,
+ const float* metadata) {
+ ExynosDevice *exynosDevice = checkDevice(dev);
+ if (exynosDevice) {
+ ExynosDisplay *exynosDisplay = checkDisplay(exynosDevice, display);
+ if (exynosDisplay) {
+ ExynosLayer *exynosLayer = checkLayer(exynosDisplay, layer);
+ if (exynosLayer == NULL) {
+ ALOGE("%s:: invalid layer", __func__);
+ return HWC2_ERROR_BAD_PARAMETER;
+ }
+ return exynosLayer->setLayerPerFrameMetadata(numElements, keys, metadata);
+ }
+ }
+ return HWC2_ERROR_BAD_DISPLAY;
+}
+
+int32_t exynos_getPerFrameMetadataKeys(hwc2_device_t* __unused dev, hwc2_display_t __unused display,
+ uint32_t* outNumKeys, int32_t* /*hwc2_per_frame_metadata_key_t*/ outKeys) {
+ if (outKeys == NULL) {
+ *outNumKeys = HWC2_MAX_FRAME_AVERAGE_LIGHT_LEVEL + 1;
+ return NO_ERROR;
+ } else {
+ if (*outNumKeys != (HWC2_MAX_FRAME_AVERAGE_LIGHT_LEVEL + 1)) {
+ ALOGE("%s:: invalid outNumKeys(%d)", __func__, *outNumKeys);
+ return -1;
+ }
+ for (uint32_t i = 0; i < (*outNumKeys) ; i++) {
+ outKeys[i] = i;
+ }
+ }
+ return NO_ERROR;
+}
+ /* ************************************************************************************/
+
+
+void exynos_boot_finished(ExynosHWCCtx *dev)
+{
+ ALOGI("%s +", __func__);
+ int sw_fd;
+
+ if (dev == NULL) {
+ ALOGE("%s:: dev is NULL", __func__);
+ return;
+ }
+
+ char cablestate_name[MAX_DEV_NAME + 1];
+ cablestate_name[MAX_DEV_NAME] = '\0';
+ sprintf(cablestate_name, DP_CABLE_STATE_NAME, DP_LINK_NAME);
+ sw_fd = open(cablestate_name, O_RDONLY);
+
+ if (sw_fd >= 0) {
+ char val;
+ if (read(sw_fd, &val, 1) == 1 && val == '1') {
+ ALOGI("%s : try to reconnect displayport", __func__);
+ ExynosExternalDisplayModule *display = (ExynosExternalDisplayModule*)dev->device->getDisplay(HWC_DISPLAY_EXTERNAL);
+ display->handleHotplugEvent();
+ }
+ hwcFdClose(sw_fd);
+ }
+ ALOGI("%s -", __func__);
+}
+
+int exynos_close(hw_device_t* device)
+{
+ if (device == NULL)
+ {
+ ALOGE("%s:: device is null", __func__);
+ return -EINVAL;
+ }
+
+ /* For HWC2.x version */
+ struct exynos_hwc2_device_t *dev = (struct exynos_hwc2_device_t *)device;
+ if (dev != NULL) {
+ if (dev->device != NULL)
+ delete dev->device;
+ delete dev;
+ }
+
+ return NO_ERROR;
+}
+
+int exynos_open(const struct hw_module_t *module, const char *name,
+ struct hw_device_t **device)
+{
+ if (strcmp(name, HWC_HARDWARE_COMPOSER)) {
+ return -EINVAL;
+ }
+
+ void *ptrDev = NULL;
+
+ ALOGD("HWC module_api_version(%d), hal_api_version(%d)",
+ module->module_api_version, module->hal_api_version);
+ /* For HWC2.x version */
+ struct exynos_hwc2_device_t *dev;
+ dev = (struct exynos_hwc2_device_t *)malloc(sizeof(*dev));
+ memset(dev, 0, sizeof(*dev));
+
+ dev->device = new ExynosDevice;
+ g_exynosDevice = dev->device;
+
+ dev->base.common.tag = HARDWARE_DEVICE_TAG;
+ dev->base.common.version = HWC_DEVICE_API_VERSION_2_0;
+ dev->base.common.module = const_cast<hw_module_t *>(module);
+ dev->base.common.close = exynos_close;
+
+ dev->base.getCapabilities = exynos_getCapabilities;
+ dev->base.getFunction = exynos_getFunction;
+ *device = &dev->base.common;
+ ptrDev = dev;
+
+ ALOGD("Start HWCService");
+#ifdef USES_HWC_SERVICES
+ ExynosHWCCtx *hwcCtx = (ExynosHWCCtx*)ptrDev;
+ android::ExynosHWCService *HWCService;
+ HWCService = android::ExynosHWCService::getExynosHWCService();
+ HWCService->setExynosHWCCtx(hwcCtx);
+ HWCService->setBootFinishedCallback(exynos_boot_finished);
+#endif
+
+ return NO_ERROR;
+}
+
+static struct hw_module_methods_t exynos_hwc_module_methods = {
+ .open = exynos_open,
+};
+
+hwc_module_t HAL_MODULE_INFO_SYM = {
+ .common = {
+ .tag = HARDWARE_MODULE_TAG,
+ .module_api_version = 2,
+ .hal_api_version = 0,
+ .id = HWC_HARDWARE_MODULE_ID,
+ .name = "Samsung exynos hwcomposer module",
+ .author = "Samsung LSI",
+ .methods = &exynos_hwc_module_methods,
+ .dso = 0,
+ .reserved = {0},
+ }
+};