blob: c620eaf81e8ab847e272ecdcf1df22fad986744a [file] [log] [blame]
/*
* 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"
#include "ExynosDeviceModule.h"
#include "ExynosResourceManager.h"
class ExynosHWCService;
using namespace android;
/**************************************************************************************
* 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>(NULL), //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
reinterpret_cast<hwc2_function_pointer_t>(exynos_setReadbackBuffer), //HWC2_FUNCTION_SET_READBACK_BUFFER
reinterpret_cast<hwc2_function_pointer_t>(exynos_getReadbackBufferAttributes), //HWC2_FUNCTION_GET_READBACK_BUFFER_ATTRIBUTES
reinterpret_cast<hwc2_function_pointer_t>(exynos_getReadbackBufferFence), //HWC2_FUNCTION_GET_READBACK_BUFFER_FENCE
#ifdef HWC_SUPPORT_RENDER_INTENT
reinterpret_cast<hwc2_function_pointer_t>(exynos_getRenderIntents), //HWC2_FUNCTION_GET_RENDER_INTENTS
reinterpret_cast<hwc2_function_pointer_t>(exynos_setColorModeWithRenderIntent), //HWC2_FUNCTION_SET_COLOR_MODE_WITH_RENDER_INTENT
#else
reinterpret_cast<hwc2_function_pointer_t>(NULL), //HWC2_FUNCTION_GET_RENDER_INTENTS
reinterpret_cast<hwc2_function_pointer_t>(NULL), //HWC2_FUNCTION_SET_COLOR_MODE_WITH_RENDER_INTENT
#endif
reinterpret_cast<hwc2_function_pointer_t>(NULL), //HWC2_FUNCTION_GET_DATASPACE_SATURATION_MATRIX
// composer 2.3
reinterpret_cast<hwc2_function_pointer_t>(exynos_getDisplayIdentificationData), //HWC2_FUNCTION_GET_DISPLAY_IDENTIFICATION_DATA
reinterpret_cast<hwc2_function_pointer_t>(exynos_getDisplayCapabilities), //HWC2_FUNCTION_GET_DISPLAY_CAPABILITIES
reinterpret_cast<hwc2_function_pointer_t>(exynos_setLayerColorTransform), //HWC2_FUNCTION_SET_LAYER_COLOR_TRANSFORM
reinterpret_cast<hwc2_function_pointer_t>(NULL), //HWC2_FUNCTION_GET_DISPLAYED_CONTENT_SAMPLING_ATTRIBUTES
reinterpret_cast<hwc2_function_pointer_t>(NULL), //HWC2_FUNCTION_SET_DISPLAYED_CONTENT_SAMPLING_ENABLED
reinterpret_cast<hwc2_function_pointer_t>(NULL), //HWC2_FUNCTION_GET_DISPLAYED_CONTENT_SAMPLE
reinterpret_cast<hwc2_function_pointer_t>(exynos_setLayerPerFrameMetadataBlobs), //HWC2_FUNCTION_SET_LAYER_PER_FRAME_METADATA_BLOBS
reinterpret_cast<hwc2_function_pointer_t>(exynos_getDisplayBrightnessSupport), //HWC2_FUNCTION_GET_DISPLAY_BRIGHTNESS_SUPPORT
reinterpret_cast<hwc2_function_pointer_t>(exynos_setDisplayBrightness), //HWC2_FUNCTION_SET_DISPLAY_BRIGHTNESS
// composer 2.4
reinterpret_cast<hwc2_function_pointer_t>(exynos_GetDisplayConnectionType), //HWC2_FUNCTION_GET_DISPLAY_CONNECTION_TYPE
reinterpret_cast<hwc2_function_pointer_t>(exynos_GetDisplayVsyncPeriod), //HWC2_FUNCTION_GET_DISPLAY_VSYNC_PERIOD
reinterpret_cast<hwc2_function_pointer_t>(exynos_SetActiveConfigWithConstraints), //HWC2_FUNCTION_SET_ACTIVE_CONFIG_WITH_CONSTRAINTS
reinterpret_cast<hwc2_function_pointer_t>(exynos_SetAutoLowLatencyMode), //HWC2_FUNCTION_SET_AUTO_LOW_LATENCY_MODE
reinterpret_cast<hwc2_function_pointer_t>(exynos_GetSupportedContentTypes), //HWC2_FUNCTION_GET_SUPPORTED_CONTENT_TYPES
reinterpret_cast<hwc2_function_pointer_t>(exynos_SetContentType), //HWC2_FUNCTION_SET_CONTENT_TYPE
reinterpret_cast<hwc2_function_pointer_t>(exynos_GetClientTargetProperty), //HWC2_FUNCTION_GET_CLIENT_TARGET_PROPERTY
reinterpret_cast<hwc2_function_pointer_t>(NULL), //HWC2_FUNCTION_SET_LAYER_GENERIC_METADATA
reinterpret_cast<hwc2_function_pointer_t>(exynos_GetLayerGenericMetadataKey), //HWC2_FUNCTION_GET_LAYER_GENERIC_METADATA_KEY
};
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,
bool printError = true) {
return exynosDisplay->checkLayer(layer, printError);
}
hwc2_function_pointer_t exynos_getFunction(struct hwc2_device *dev,
int32_t descriptor) {
if (descriptor <= HWC2_FUNCTION_INVALID || descriptor > HWC2_FUNCTION_GET_LAYER_GENERIC_METADATA_KEY)
return NULL;
ExynosDevice *exynosDevice = checkDevice(dev);
if (!exynosDevice)
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) {
int32_t ret = exynosDisplay->acceptDisplayChanges();
return ret;
}
}
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 exynosDevice->createLayer(exynosDisplay, 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) {
if (format == nullptr)
return HWC2_ERROR_BAD_PARAMETER;
ExynosDevice *exynosDevice = checkDevice(dev);
*outDisplay = getDisplayId(HWC_DISPLAY_VIRTUAL, 0);
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) {
return exynosDevice->destroyLayer(exynosDisplay, layer);
}
}
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 exynosDevice->getColorModes(exynosDisplay, outNumModes, outModes);
}
return HWC2_ERROR_BAD_DISPLAY;
}
int32_t exynos_getRenderIntents(hwc2_device_t *dev, hwc2_display_t display, int32_t mode,
uint32_t *outNumIntents, int32_t * /*android_render_intent_v1_1_t*/ outIntents) {
if (mode < 0)
return HWC2_ERROR_BAD_PARAMETER;
ExynosDevice *exynosDevice = checkDevice(dev);
ALOGD("%s:: mode(%d)", __func__, mode);
if (exynosDevice) {
ExynosDisplay *exynosDisplay = checkDisplay(exynosDevice, display);
if (exynosDisplay)
return exynosDisplay->getRenderIntents(mode, outNumIntents, outIntents);
}
return HWC2_ERROR_BAD_DISPLAY;
}
int32_t exynos_setColorModeWithRenderIntent(hwc2_device_t *dev, hwc2_display_t display,
int32_t /*android_color_mode_t*/ mode,
int32_t /*android_render_intent_v1_1_t */ intent) {
if ((mode < 0) || (intent < 0))
return HWC2_ERROR_BAD_PARAMETER;
ExynosDevice *exynosDevice = checkDevice(dev);
ALOGD("%s:: mode(%d), intent(%d)", __func__, mode, intent);
if (exynosDevice) {
ExynosDisplay *exynosDisplay = checkDisplay(exynosDevice, display);
if (exynosDisplay)
return exynosDevice->setColorModeWithRenderIntent(exynosDisplay, mode, intent);
}
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 *outNumTypes,
int32_t *outTypes, float *outMaxLuminance,
float *outMaxAverageLuminance, float *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 *outPresentFence) {
ExynosDevice *exynosDevice = checkDevice(dev);
if (exynosDevice) {
ExynosDisplay *exynosDisplay = checkDisplay(exynosDevice, display);
if (exynosDisplay == NULL)
return HWC2_ERROR_BAD_DISPLAY;
return exynosDevice->presentDisplay(exynosDisplay, outPresentFence);
}
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 = HWC2_ERROR_NONE;
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_INVALID:
case HWC2_CALLBACK_HOTPLUG:
case HWC2_CALLBACK_REFRESH:
case HWC2_CALLBACK_VSYNC:
case HWC2_CALLBACK_VSYNC_2_4:
case HWC2_CALLBACK_VSYNC_PERIOD_TIMING_CHANGED:
ret = exynosDevice->registerCallback(descriptor, callbackData, pointer);
break;
default:
ret = HWC2_ERROR_BAD_PARAMETER;
break;
}
if ((descriptor == HWC2_CALLBACK_HOTPLUG) && (pointer == nullptr)) {
/* [HACK] Composer client is destroyed */
ALOGI("Registered hot plug callcack is null");
exynosDevice->resetForDestroyClient();
}
return ret;
}
int32_t exynos_setActiveConfig(hwc2_device_t *dev, hwc2_display_t display,
hwc2_config_t config) {
HDEBUGLOGD(eDebugDisplayConfig, "%s, %d", __func__, config);
ExynosDevice *exynosDevice = checkDevice(dev);
if (exynosDevice) {
ExynosDisplay *exynosDisplay = checkDisplay(exynosDevice, display);
if (exynosDisplay) {
return exynosDevice->setActiveConfig(exynosDisplay, 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 exynosDevice->setClientTarget(exynosDisplay, target,
acquireFence, dataspace);
}
return HWC2_ERROR_BAD_DISPLAY;
}
int32_t exynos_setColorMode(hwc2_device_t *dev, hwc2_display_t display, int32_t mode) {
if (mode < 0)
return HWC2_ERROR_BAD_PARAMETER;
ExynosDevice *exynosDevice = checkDevice(dev);
if (exynosDevice) {
ExynosDisplay *exynosDisplay = checkDisplay(exynosDevice, display);
if (exynosDisplay)
return exynosDevice->setColorMode(exynosDisplay, mode);
}
return HWC2_ERROR_BAD_DISPLAY;
}
int32_t exynos_setColorTransform(hwc2_device_t *dev, hwc2_display_t display,
const float *matrix, int32_t hint) {
if (matrix == nullptr)
return HWC2_ERROR_BAD_PARAMETER;
ExynosDevice *exynosDevice = checkDevice(dev);
if (exynosDevice) {
ExynosDisplay *exynosDisplay = checkDisplay(exynosDevice, display);
if (exynosDisplay)
return exynosDevice->setColorTransform(exynosDisplay, 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, false);
if (exynosLayer)
return exynosDisplay->setCursorPositionAsync(x, y);
}
}
return HWC2_ERROR_NONE;
}
int32_t exynos_setLayerBlendMode(hwc2_device_t *dev, hwc2_display_t display,
hwc2_layer_t layer, int32_t /*hwc2_blend_mode_t*/ mode) {
ExynosDevice *exynosDevice = checkDevice(dev);
if (exynosDevice) {
ExynosDisplay *exynosDisplay = checkDisplay(exynosDevice, display);
if (exynosDisplay) {
ExynosLayer *exynosLayer = checkLayer(exynosDisplay, layer);
if (exynosLayer)
return exynosDevice->setLayerBlendMode(exynosLayer, 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) {
return exynosDevice->setLayerBuffer(exynosDisplay,
layer, 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 exynosDevice->setLayerCompositionType(exynosLayer, 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) {
return exynosDevice->setLayerDataspace(exynosDisplay, layer,
dataspace);
}
}
return HWC2_ERROR_BAD_LAYER;
}
int32_t exynos_setLayerDisplayFrame(hwc2_device_t *dev, hwc2_display_t display,
hwc2_layer_t layer, hwc_rect_t frame) {
ExynosDevice *exynosDevice = checkDevice(dev);
if (exynosDevice) {
ExynosDisplay *exynosDisplay = checkDisplay(exynosDevice, display);
if (exynosDisplay) {
ExynosLayer *exynosLayer = checkLayer(exynosDisplay, layer);
if (exynosLayer)
return exynosDevice->setLayerDisplayFrame(exynosLayer, frame);
}
}
return HWC2_ERROR_BAD_LAYER;
}
int32_t exynos_setLayerPlaneAlpha(hwc2_device_t *dev, hwc2_display_t display,
hwc2_layer_t layer, float 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_setLayerSourceCrop(hwc2_device_t *dev, hwc2_display_t display,
hwc2_layer_t layer, hwc_frect_t crop) {
ExynosDevice *exynosDevice = checkDevice(dev);
if (exynosDevice) {
ExynosDisplay *exynosDisplay = checkDisplay(exynosDevice, display);
if (exynosDisplay) {
ExynosLayer *exynosLayer = checkLayer(exynosDisplay, layer);
if (exynosLayer)
return exynosDevice->setLayerSourceCrop(exynosLayer, crop);
}
}
return HWC2_ERROR_BAD_LAYER;
}
int32_t exynos_setLayerSurfaceDamage(hwc2_device_t *dev, hwc2_display_t display,
hwc2_layer_t layer, hwc_region_t 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 display,
hwc2_layer_t layer, int32_t /*hwc_transform_t*/ transform) {
ExynosDevice *exynosDevice = checkDevice(dev);
if (exynosDevice) {
ExynosDisplay *exynosDisplay = checkDisplay(exynosDevice, display);
if (exynosDisplay) {
ExynosLayer *exynosLayer = checkLayer(exynosDisplay, layer);
if (exynosLayer)
return exynosDevice->setLayerTransform(exynosLayer, transform);
}
}
return HWC2_ERROR_BAD_LAYER;
}
int32_t exynos_setLayerVisibleRegion(hwc2_device_t *dev, hwc2_display_t display,
hwc2_layer_t layer, hwc_region_t 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 exynosDevice->setLayerZOrder(exynosLayer, 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 display,
int32_t /*hwc2_power_mode_t*/ mode) {
if (mode < 0)
return HWC2_ERROR_BAD_PARAMETER;
ExynosDevice *exynosDevice = checkDevice(dev);
if (exynosDevice) {
ExynosDisplay *exynosDisplay = checkDisplay(exynosDevice, display);
if (exynosDisplay) {
int32_t ret = exynosDevice->setPowerMode(exynosDisplay, mode);
return ret;
}
}
return HWC2_ERROR_BAD_DISPLAY;
}
int32_t exynos_setVsyncEnabled(hwc2_device_t *dev, hwc2_display_t display,
int32_t /*hwc2_vsync_t*/ 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 *dev, hwc2_display_t display,
uint32_t *outNumTypes, uint32_t *outNumRequests) {
ExynosDevice *exynosDevice = checkDevice(dev);
if (!exynosDevice)
return HWC2_ERROR_BAD_DISPLAY;
ExynosDisplay *exynosDisplay = checkDisplay(exynosDevice, display);
if (!exynosDisplay)
return HWC2_ERROR_BAD_DISPLAY;
return exynosDevice->validateDisplay(exynosDisplay,
outNumTypes, outNumRequests);
}
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) {
if ((keys == nullptr) || (metadata == nullptr))
return HWC2_ERROR_BAD_PARAMETER;
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 *dev, hwc2_display_t __unused display,
uint32_t *outNumKeys, int32_t * /*hwc2_per_frame_metadata_key_t*/ outKeys) {
ExynosDevice *exynosDevice = checkDevice(dev);
if (exynosDevice == NULL)
return HWC2_ERROR_BAD_DISPLAY;
ExynosResourceManager *resourceManager = exynosDevice->mResourceManager;
uint32_t numKeys = 0;
if (resourceManager->hasHDR10PlusMPP())
numKeys = HWC2_HDR10_PLUS_SEI;
else
numKeys = HWC2_MAX_FRAME_AVERAGE_LIGHT_LEVEL;
if (outKeys == NULL) {
*outNumKeys = numKeys + 1;
return NO_ERROR;
} else {
if (*outNumKeys != (numKeys + 1)) {
ALOGE("%s:: invalid outNumKeys(%d)", __func__, *outNumKeys);
return -1;
}
for (uint32_t i = 0; i < (*outNumKeys); i++) {
outKeys[i] = i;
}
}
return NO_ERROR;
}
int32_t exynos_getReadbackBufferAttributes(hwc2_device_t *dev, hwc2_display_t display,
int32_t * /*android_pixel_format_t*/ outFormat,
int32_t * /*android_dataspace_t*/ outDataspace) {
ExynosDevice *exynosDevice = checkDevice(dev);
if (exynosDevice) {
ExynosDisplay *exynosDisplay = checkDisplay(exynosDevice, display);
if (exynosDisplay)
return exynosDisplay->getReadbackBufferAttributes(outFormat, outDataspace);
}
return HWC2_ERROR_BAD_DISPLAY;
}
int32_t exynos_getDisplayIdentificationData(hwc2_device_t *dev, hwc2_display_t display, uint8_t *outPort,
uint32_t *outDataSize, uint8_t *outData) {
ExynosDevice *exynosDevice = checkDevice(dev);
if (exynosDevice) {
ExynosDisplay *exynosDisplay = checkDisplay(exynosDevice, display);
if (exynosDisplay) {
return exynosDisplay->getDisplayIdentificationData(outPort, outDataSize, outData);
}
}
return HWC2_ERROR_BAD_DISPLAY;
}
int32_t exynos_setReadbackBuffer(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->setReadbackBuffer(buffer, releaseFence);
}
return HWC2_ERROR_BAD_DISPLAY;
}
int32_t exynos_getDisplayCapabilities(hwc2_device_t *dev, hwc2_display_t display, uint32_t *outNumCapabilities,
uint32_t *outCapabilities) {
ExynosDevice *exynosDevice = checkDevice(dev);
if (exynosDevice) {
ExynosDisplay *exynosDisplay = checkDisplay(exynosDevice, display);
if (exynosDisplay) {
return exynosDisplay->getDisplayCapabilities(outNumCapabilities, outCapabilities);
}
}
return HWC2_ERROR_BAD_DISPLAY;
}
int32_t exynos_setLayerColorTransform(hwc2_device_t *dev,
hwc2_display_t display, hwc2_layer_t layer, const float *matrix) {
if (matrix == nullptr)
return HWC2_ERROR_BAD_PARAMETER;
ExynosDevice *exynosDevice = checkDevice(dev);
if (exynosDevice) {
ExynosDisplay *exynosDisplay = checkDisplay(exynosDevice, display);
if (exynosDisplay) {
ExynosLayer *exynosLayer = checkLayer(exynosDisplay, layer);
if (exynosLayer)
return exynosLayer->setLayerColorTransform(matrix);
}
}
return HWC2_ERROR_BAD_DISPLAY;
}
int32_t exynos_getReadbackBufferFence(hwc2_device_t *dev, hwc2_display_t display,
int32_t *outFence) {
ExynosDevice *exynosDevice = checkDevice(dev);
if (exynosDevice) {
ExynosDisplay *exynosDisplay = checkDisplay(exynosDevice, display);
if (exynosDisplay)
return exynosDisplay->getReadbackBufferFence(outFence);
}
return HWC2_ERROR_BAD_DISPLAY;
}
int32_t exynos_setLayerPerFrameMetadataBlobs(hwc2_device_t *dev, hwc2_display_t display,
hwc2_layer_t layer, uint32_t numElements, const int32_t *keys, const uint32_t *sizes,
const uint8_t *metadata) {
if ((keys == nullptr) || (sizes == nullptr) || (metadata == nullptr))
return HWC2_ERROR_BAD_PARAMETER;
ExynosDevice *exynosDevice = checkDevice(dev);
if (exynosDevice) {
ExynosDisplay *exynosDisplay = checkDisplay(exynosDevice, display);
if (exynosDisplay) {
ExynosLayer *exynosLayer = checkLayer(exynosDisplay, layer);
if (exynosLayer)
return exynosLayer->setLayerPerFrameMetadataBlobs(numElements, keys, sizes, metadata);
}
}
return HWC2_ERROR_BAD_DISPLAY;
}
int32_t exynos_getDisplayBrightnessSupport(hwc2_device_t *dev, hwc2_display_t display, bool *outSupport) {
ExynosDevice *exynosDevice = checkDevice(dev);
if (exynosDevice) {
ExynosDisplay *exynosDisplay = checkDisplay(exynosDevice, display);
if (exynosDisplay) {
return exynosDisplay->getDisplayBrightnessSupport(outSupport);
}
}
return HWC2_ERROR_BAD_DISPLAY;
}
int32_t exynos_setDisplayBrightness(hwc2_device_t *dev, hwc2_display_t display, float brightness) {
ExynosDevice *exynosDevice = checkDevice(dev);
if (exynosDevice) {
ExynosDisplay *exynosDisplay = checkDisplay(exynosDevice, display);
if (exynosDisplay) {
return exynosDisplay->setDisplayBrightness(brightness);
}
}
return HWC2_ERROR_BAD_DISPLAY;
}
int32_t exynos_GetDisplayConnectionType(hwc2_device_t *dev, hwc2_display_t display,
uint32_t * /*hwc2_display_connection_type_t*/ outType) {
ExynosDevice *exynosDevice = checkDevice(dev);
if (exynosDevice) {
ExynosDisplay *exynosDisplay = checkDisplay(exynosDevice, display);
if (exynosDisplay) {
return exynosDisplay->getDisplayConnectionType(outType);
}
}
return HWC2_ERROR_BAD_DISPLAY;
}
int32_t exynos_GetDisplayVsyncPeriod(hwc2_device_t *dev, hwc2_display_t display,
hwc2_vsync_period_t *outVsyncPeriod) {
ExynosDevice *exynosDevice = checkDevice(dev);
if (exynosDevice) {
ExynosDisplay *exynosDisplay = checkDisplay(exynosDevice, display);
if (exynosDisplay) {
return exynosDisplay->getDisplayVsyncPeriod(outVsyncPeriod);
}
}
return HWC2_ERROR_BAD_DISPLAY;
}
int32_t exynos_SetActiveConfigWithConstraints(hwc2_device_t *dev, hwc2_display_t display,
hwc2_config_t config, hwc_vsync_period_change_constraints_t *vsyncPeriodChangeConstraints,
hwc_vsync_period_change_timeline_t *outTimeline) {
HDEBUGLOGD(eDebugDisplayConfig, "%s, %d", __func__, config);
ExynosDevice *exynosDevice = checkDevice(dev);
if (exynosDevice) {
ExynosDisplay *exynosDisplay = checkDisplay(exynosDevice, display);
if (exynosDisplay) {
return exynosDevice->setActiveConfigWithConstraints(exynosDisplay, config, vsyncPeriodChangeConstraints, outTimeline);
}
}
return HWC2_ERROR_BAD_DISPLAY;
}
int32_t exynos_SetAutoLowLatencyMode(hwc2_device_t *dev, hwc2_display_t display, bool on) {
ExynosDevice *exynosDevice = checkDevice(dev);
if (exynosDevice) {
ExynosDisplay *exynosDisplay = checkDisplay(exynosDevice, display);
if (exynosDisplay) {
return exynosDisplay->setAutoLowLatencyMode(on);
}
}
return HWC2_ERROR_BAD_DISPLAY;
}
int32_t exynos_GetSupportedContentTypes(hwc2_device_t *dev, hwc2_display_t display,
uint32_t *outNumSupportedContentTypes, uint32_t *outSupportedContentTypes) {
ExynosDevice *exynosDevice = checkDevice(dev);
if (exynosDevice) {
ExynosDisplay *exynosDisplay = checkDisplay(exynosDevice, display);
if (exynosDisplay) {
return exynosDisplay->getSupportedContentTypes(outNumSupportedContentTypes, outSupportedContentTypes);
}
}
return HWC2_ERROR_BAD_DISPLAY;
}
int32_t exynos_SetContentType(hwc2_device_t *dev, hwc2_display_t display,
int32_t /* hwc2_content_type_t */ contentType) {
ExynosDevice *exynosDevice = checkDevice(dev);
if (exynosDevice) {
ExynosDisplay *exynosDisplay = checkDisplay(exynosDevice, display);
if (exynosDisplay) {
return exynosDisplay->setContentType(contentType);
}
}
return HWC2_ERROR_BAD_DISPLAY;
}
int32_t exynos_GetClientTargetProperty(hwc2_device_t *dev, hwc2_display_t display,
hwc_client_target_property_t *outClientTargetProperty) {
ExynosDevice *exynosDevice = checkDevice(dev);
if (exynosDevice) {
ExynosDisplay *exynosDisplay = checkDisplay(exynosDevice, display);
if (exynosDisplay) {
/* TODO */
return exynosDisplay->getClientTargetProperty(outClientTargetProperty);
}
}
return HWC2_ERROR_BAD_DISPLAY;
}
void exynos_GetLayerGenericMetadataKey(hwc2_device_t *dev, uint32_t keyIndex,
uint32_t *outKeyLength, char *outKey, bool *outMandatory) {
ExynosDevice *exynosDevice = checkDevice(dev);
if (exynosDevice) {
return exynosDevice->getLayerGenericMetadataKey(keyIndex, outKeyLength, outKey, outMandatory);
}
return;
}
/* ************************************************************************************/
void exynos_boot_finished(ExynosDevice *dev) {
ALOGI("%s +", __func__);
if (dev == NULL) {
ALOGE("%s:: dev is NULL", __func__);
return;
}
dev->handleHotplugAfterBooting();
dev->mIsBootFinished = true;
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 ExynosDeviceModule;
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();
if (HWCService != nullptr) {
HWCService->setExynosDevice(hwcCtx->device);
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},
}};